ruby_mvc 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +14 -0
- data/lib/ruby_mvc.rb +3 -1
- data/lib/ruby_mvc/application.rb +52 -2
- data/lib/ruby_mvc/controllers.rb +28 -0
- data/lib/ruby_mvc/controllers/action.rb +93 -0
- data/lib/ruby_mvc/controllers/action_group.rb +70 -0
- data/lib/ruby_mvc/controllers/app_controller.rb +4 -2
- data/lib/ruby_mvc/controllers/rails_controller.rb +2 -0
- data/lib/ruby_mvc/models.rb +2 -0
- data/lib/ruby_mvc/models/ar_table_model.rb +133 -0
- data/lib/ruby_mvc/models/array_table_model.rb +81 -13
- data/lib/ruby_mvc/models/keyed_array_table_model.rb +1 -1
- data/lib/ruby_mvc/models/model.rb +129 -0
- data/lib/ruby_mvc/models/table_model.rb +107 -10
- data/lib/ruby_mvc/models/view_model_template.rb +140 -0
- data/lib/ruby_mvc/renderers.rb +1 -0
- data/lib/ruby_mvc/renderers/html4_table_model_renderer.rb +7 -6
- data/lib/ruby_mvc/renderers/hyperlink_cell_renderer.rb +47 -0
- data/lib/ruby_mvc/toolkit.rb +5 -1
- data/lib/ruby_mvc/toolkit/browser_history.rb +115 -0
- data/lib/ruby_mvc/toolkit/dialog.rb +12 -1
- data/lib/ruby_mvc/toolkit/frame.rb +3 -1
- data/lib/ruby_mvc/toolkit/grid_view.rb +46 -0
- data/lib/ruby_mvc/toolkit/messagebox.rb +32 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby.rb +5 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/app.rb +23 -2
- data/lib/ruby_mvc/toolkit/peers/wxruby/common.rb +11 -1
- data/lib/ruby_mvc/toolkit/peers/wxruby/dialog.rb +82 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/form_builder.rb +108 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/frame.rb +85 -1
- data/lib/ruby_mvc/toolkit/peers/wxruby/grid_model.rb +79 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/grid_view.rb +117 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/messagebox.rb +58 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/web_view.rb +40 -10
- data/lib/ruby_mvc/toolkit/property_change_notifier.rb +46 -0
- data/lib/ruby_mvc/toolkit/signal_handler.rb +149 -0
- data/lib/ruby_mvc/toolkit/web_view.rb +1 -1
- data/lib/ruby_mvc/toolkit/widget.rb +13 -6
- data/lib/ruby_mvc/views.rb +8 -59
- data/lib/ruby_mvc/views/{ar_type_list.rb → ar_form_view.rb} +10 -13
- data/lib/ruby_mvc/views/ar_support.rb +29 -0
- data/lib/ruby_mvc/views/ar_type_editor.rb +17 -28
- data/lib/ruby_mvc/views/ar_web_model_view.rb +59 -0
- data/lib/ruby_mvc/views/ar_web_type_list.rb +44 -0
- data/lib/ruby_mvc/views/browser_view.rb +185 -0
- data/lib/ruby_mvc/views/form_view.rb +111 -0
- data/lib/ruby_mvc/views/grid_table_view.rb +96 -0
- data/lib/ruby_mvc/views/table_view.rb +0 -39
- data/lib/ruby_mvc/views/view.rb +121 -0
- data/lib/ruby_mvc/views/web_content_table_view.rb +40 -0
- data/lib/ruby_mvc/views/{web_view.rb → web_content_view.rb} +17 -28
- data/lib/ruby_mvc/views/web_model_view.rb +67 -0
- data/ruby_mvc.gemspec +1 -1
- data/sample/browser_view.rb +57 -0
- data/sample/form.rb +59 -0
- data/sample/form2.rb +63 -0
- data/sample/grid_table_view.rb +68 -0
- data/sample/grid_view.rb +44 -0
- data/sample/grid_view2.rb +57 -0
- data/sample/test.html +1 -0
- data/sample/test2.html +33 -0
- data/sample/web_view.rb +4 -0
- data/test/unit/models/test_array_table_model.rb +19 -3
- data/test/unit/models/test_keyed_array_table_model.rb +3 -2
- data/test/unit/models/test_model.rb +88 -0
- metadata +39 -20
- data/lib/ruby_mvc/toolkit/notification.rb +0 -202
- data/lib/ruby_mvc/views/ar_model_editor.rb +0 -84
@@ -23,35 +23,103 @@
|
|
23
23
|
#####################################################################
|
24
24
|
#++
|
25
25
|
|
26
|
-
module
|
26
|
+
module RubyMVC
|
27
27
|
module Models
|
28
28
|
|
29
|
-
# This class
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
29
|
+
# This class provides an adapter to expose an array of
|
30
|
+
# hashes or anything else that responds to the #keys, #[]
|
31
|
+
# and #[]= methods as a TableModel instance.
|
32
|
+
#
|
33
|
+
# Note that the keys of the objects in the array will be
|
34
|
+
# requested as symbols and not as any other object type.
|
35
35
|
|
36
|
-
class
|
37
|
-
def initialize(data)
|
36
|
+
class HashArrayTableModel < TableModel
|
37
|
+
def initialize(data, options = {})
|
38
|
+
raise ArgumentError, "argument not an Array" if !data.is_a? Array
|
39
|
+
super(options)
|
40
|
+
|
41
|
+
@options = options
|
38
42
|
@data = data
|
39
43
|
end
|
40
44
|
|
45
|
+
def create_rows(count = 1)
|
46
|
+
if f = @options[:row_factory]
|
47
|
+
f.call(count)
|
48
|
+
else
|
49
|
+
r = []
|
50
|
+
t = @options[:row_template] || @data.last
|
51
|
+
count.times { r << t.clone }
|
52
|
+
r
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def insert_row(index, row)
|
57
|
+
@data.insert(index, row)
|
58
|
+
super(index, Model.adapt(row, @options))
|
59
|
+
end
|
60
|
+
|
61
|
+
def insert_rows(index, rows)
|
62
|
+
@data.insert(index, *rows)
|
63
|
+
super(index, rows.collect { |r| Model.adapt(r, @options) })
|
64
|
+
end
|
65
|
+
|
66
|
+
def remove_row(index)
|
67
|
+
row = Model.adapt(@data.delete_at(index), @options)
|
68
|
+
signal_emit("rows-removed", self, index, [ row ])
|
69
|
+
row
|
70
|
+
end
|
71
|
+
|
72
|
+
def remove_rows(index, count)
|
73
|
+
rows = []
|
74
|
+
count.times do
|
75
|
+
rows << Model.adapt(@data.delete_at(index), @options)
|
76
|
+
end
|
77
|
+
signal_emit("rows-removed", self, index, rows)
|
78
|
+
rows
|
79
|
+
end
|
80
|
+
|
81
|
+
def update_row(index, row)
|
82
|
+
@data[index] = row
|
83
|
+
super(index, Model.adapt(row, @options))
|
84
|
+
end
|
85
|
+
|
86
|
+
# The keys used will come from the first element in the
|
87
|
+
# array or be empty if the array is empty.
|
88
|
+
|
41
89
|
def keys
|
42
|
-
if @data
|
43
|
-
@data.keys
|
90
|
+
if @data.size > 0
|
91
|
+
@data.first.keys
|
44
92
|
else
|
45
93
|
{}
|
46
94
|
end
|
47
95
|
end
|
48
96
|
|
97
|
+
def value_for(row, key)
|
98
|
+
@data[row][key.to_sym]
|
99
|
+
end
|
100
|
+
|
101
|
+
def [](row)
|
102
|
+
@data[row]
|
103
|
+
end
|
104
|
+
|
105
|
+
# Iterates over each of the elements in the array and
|
106
|
+
# provides a Model instance to the caller based on the
|
107
|
+
# keys contained in the object itself.
|
108
|
+
|
49
109
|
def each(&block)
|
50
|
-
|
110
|
+
return if !block
|
111
|
+
|
112
|
+
@data.each do |x|
|
113
|
+
block.call(Model.adapt(x, @options))
|
114
|
+
end
|
51
115
|
end
|
52
116
|
|
53
117
|
def each_with_index(&block)
|
54
|
-
|
118
|
+
return if !block
|
119
|
+
|
120
|
+
@data.each_with_index do |x, i|
|
121
|
+
block.call(Model.adapt(x, @options), i)
|
122
|
+
end
|
55
123
|
end
|
56
124
|
end
|
57
125
|
|
@@ -0,0 +1,129 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: model.rb
|
21
|
+
# Created: Fri 30 Dec 2011 12:46:32 CET
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
module RubyMVC
|
27
|
+
module Models
|
28
|
+
|
29
|
+
# This class defines the generic API for models in RubyMVC.
|
30
|
+
# Models expose key/value pairs to other parts of the
|
31
|
+
# system, but they are more than simple Hash instances
|
32
|
+
# because not all properties of a model are always editable.
|
33
|
+
|
34
|
+
class Model
|
35
|
+
include Toolkit::SignalHandler
|
36
|
+
extend Toolkit::SignalHandler::ClassMethods
|
37
|
+
|
38
|
+
# this signal is emitted when any property is changed on
|
39
|
+
# the model. The arguments are the sender, the old and
|
40
|
+
# the new values
|
41
|
+
|
42
|
+
signal "property-changed"
|
43
|
+
|
44
|
+
# This method is used to use the Model class to adapt any
|
45
|
+
# object that responds to the #keys, #size, #[] and #[]=
|
46
|
+
# methods
|
47
|
+
|
48
|
+
def self.adapt(obj, options = {})
|
49
|
+
return obj if obj.is_a? Model
|
50
|
+
self.new(options.merge({:data => obj}))
|
51
|
+
end
|
52
|
+
|
53
|
+
# The base model is backed by a simple Hash, and supports
|
54
|
+
# specifying the following options for defining which
|
55
|
+
# properties are editable or not.
|
56
|
+
|
57
|
+
def initialize(options = {})
|
58
|
+
@data = options.delete(:data) || {}
|
59
|
+
@options = options
|
60
|
+
end
|
61
|
+
|
62
|
+
# This method is used to provide the property keys of the
|
63
|
+
# model as symbols.
|
64
|
+
|
65
|
+
def keys
|
66
|
+
@data.keys.sort.collect { |k| k.to_sym }
|
67
|
+
end
|
68
|
+
|
69
|
+
# This method is used to retrieve the property key and the
|
70
|
+
# display label for the key to be used by views when
|
71
|
+
# displaying model data.
|
72
|
+
|
73
|
+
def labels
|
74
|
+
@labels = {}
|
75
|
+
self.keys.collect do |k|
|
76
|
+
x = { :key => k.to_sym, :label => k.to_s.capitalize }
|
77
|
+
@labels[x[:key]] = x[:label]
|
78
|
+
x
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# This method is used to check whether a property key is
|
83
|
+
# editable or not
|
84
|
+
|
85
|
+
def is_editable?(key)
|
86
|
+
(@options[:editable] || {})[key.to_sym] || true
|
87
|
+
end
|
88
|
+
|
89
|
+
def [](key)
|
90
|
+
@data[key.to_sym]
|
91
|
+
end
|
92
|
+
|
93
|
+
def []=(key, val)
|
94
|
+
k = key.to_sym
|
95
|
+
old = @data[k]
|
96
|
+
@data[k] = val
|
97
|
+
|
98
|
+
if old != val
|
99
|
+
signal_emit("property-changed", self, k, old, val)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def size
|
104
|
+
@data.size
|
105
|
+
end
|
106
|
+
|
107
|
+
# This method is used to iterate over the properties of
|
108
|
+
# the model. For each property, the key, label and value
|
109
|
+
# are provide as arguments to the block
|
110
|
+
|
111
|
+
def each_label(&block)
|
112
|
+
labels.each do |l|
|
113
|
+
block.call((k = l[:key]), l[:label], @data[k])
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# This method is used to retrieve the label for the
|
118
|
+
# specified model key.
|
119
|
+
|
120
|
+
def label_for(key)
|
121
|
+
if !@labels
|
122
|
+
labels
|
123
|
+
end
|
124
|
+
@labels[key.to_sym]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
@@ -23,19 +23,116 @@
|
|
23
23
|
#####################################################################
|
24
24
|
#++
|
25
25
|
|
26
|
-
module
|
26
|
+
module RubyMVC
|
27
27
|
module Models
|
28
28
|
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
# they are expected to all have the same number of columns.
|
33
|
-
#
|
34
|
-
# Logically, each of the elements in the table model is a
|
35
|
-
# row instance that provides keyed property access to the
|
36
|
-
# data in the model based on the [] method.
|
29
|
+
# The TableModel class expands the concepts of the Model
|
30
|
+
# class to a number of related rows with the same properties
|
31
|
+
# defined for the model.
|
37
32
|
|
38
|
-
class TableModel
|
33
|
+
class TableModel < Model
|
34
|
+
# This signal is triggered when contiguous rows are
|
35
|
+
# inserted into the model. The arguments are the sender
|
36
|
+
# model, the insertion index and the row models that were
|
37
|
+
# inserted.
|
38
|
+
|
39
|
+
signal "rows-inserted"
|
40
|
+
|
41
|
+
# This signal is triggered when contiguous rows are
|
42
|
+
# removed from the model. The arguments are the index at
|
43
|
+
# which the removal took place and the row models that
|
44
|
+
# were removed from the model.
|
45
|
+
|
46
|
+
signal "rows-removed"
|
47
|
+
|
48
|
+
# This signal is triggered when an existing row has been
|
49
|
+
# changed. The arguments are the sender, the index and
|
50
|
+
# the changed row model
|
51
|
+
|
52
|
+
signal "row-changed"
|
53
|
+
|
54
|
+
# This method is used to create a number of row data
|
55
|
+
# elements that will be inserted into the model at the
|
56
|
+
# specified location using the #insert_row or #insert_rows
|
57
|
+
# method.
|
58
|
+
#
|
59
|
+
# The result is an array of row data instances in whatever
|
60
|
+
# format is deemed suitable for the model instance to
|
61
|
+
# create.
|
62
|
+
|
63
|
+
def create_rows(count = 1)
|
64
|
+
end
|
65
|
+
|
66
|
+
# This method is used to insert a single row into the
|
67
|
+
# model at the given row index.
|
68
|
+
|
69
|
+
def insert_row(index, row)
|
70
|
+
signal_emit("rows-inserted", self, index, [ row ])
|
71
|
+
end
|
72
|
+
|
73
|
+
# This method is used to insert an array of row objects
|
74
|
+
# into the model at the specified index
|
75
|
+
|
76
|
+
def insert_rows(index, rows)
|
77
|
+
signal_emit("rows-inserted", self, index, rows)
|
78
|
+
end
|
79
|
+
|
80
|
+
# This method is used remove a single row from the model
|
81
|
+
# and return a reference to the row model removed to the
|
82
|
+
# caller.
|
83
|
+
#
|
84
|
+
# Note, the derived classes are responsible for emitting
|
85
|
+
# the appropriate signal since the data access is opaque
|
86
|
+
# to the base class.
|
87
|
+
|
88
|
+
def remove_row(index)
|
89
|
+
end
|
90
|
+
|
91
|
+
# This method is used remove multiple rows from the model
|
92
|
+
# and return a reference to the row models removed to the
|
93
|
+
# caller.
|
94
|
+
#
|
95
|
+
# Note, the derived classes are responsible for emitting
|
96
|
+
# the appropriate signal since the data access is opaque
|
97
|
+
# to the base class.
|
98
|
+
|
99
|
+
def remove_rows(index, count)
|
100
|
+
end
|
101
|
+
|
102
|
+
# This method is used to update the specified row in the
|
103
|
+
# model and ensure that the appropriate notifications for
|
104
|
+
# all linked views are sent.
|
105
|
+
|
106
|
+
def update_row(index, row)
|
107
|
+
signal_emit("row-changed", index, row)
|
108
|
+
end
|
109
|
+
|
110
|
+
# This method will iterate over each of the rows and
|
111
|
+
# provide the caller with a reference to the row instance,
|
112
|
+
# which is also conformant with the Model API
|
113
|
+
|
114
|
+
def each(&block)
|
115
|
+
end
|
116
|
+
|
117
|
+
# This method will iterate over each of rows and provide
|
118
|
+
# the caller with a reference to the row instance as a
|
119
|
+
# model and the index of the row.
|
120
|
+
|
121
|
+
def each_with_index(&block)
|
122
|
+
end
|
123
|
+
|
124
|
+
# This method allows direct access into the model rows, in
|
125
|
+
# row-major order for the specified, zero-based index and
|
126
|
+
# property key
|
127
|
+
|
128
|
+
def value_for(row, key)
|
129
|
+
end
|
130
|
+
|
131
|
+
# This method is used to retrieve the model instance for
|
132
|
+
# the given row index
|
133
|
+
|
134
|
+
def [](idx)
|
135
|
+
end
|
39
136
|
end
|
40
137
|
|
41
138
|
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: view_model_template.rb
|
21
|
+
# Created: Mon 12 Dec 2011 06:30:57 CST
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
module RubyMVC
|
27
|
+
module Models
|
28
|
+
|
29
|
+
# This class provides a proxy for Model instances that
|
30
|
+
# allows them to control the visibility of which properties
|
31
|
+
# are exposed for a given view. ViewModelTemplate instances can
|
32
|
+
# be reused across view instances where the same properties
|
33
|
+
# are to be exposed.
|
34
|
+
#
|
35
|
+
# The ViewModelTemplate class implements the same interface as
|
36
|
+
# Model instances so that they can be used as drop-in
|
37
|
+
# replacements everywhere a model instance can be used.
|
38
|
+
#
|
39
|
+
# The key difference is that the ViewModelTemplate exists outside
|
40
|
+
# of any particular model instances, allowing the same view
|
41
|
+
# binding to work for numerous concrete model instances,
|
42
|
+
# effectively speifying the template through which the model
|
43
|
+
# may be accessed.
|
44
|
+
|
45
|
+
class ViewModelTemplate
|
46
|
+
attr_accessor :title
|
47
|
+
|
48
|
+
# When the ViewModelTemplate is initialized, it requires a set
|
49
|
+
# of options and/or an optional initializer block that is
|
50
|
+
# executed within the scope of the newly created instance.
|
51
|
+
|
52
|
+
def initialize(options = {}, &block)
|
53
|
+
@options = options
|
54
|
+
@labels = []
|
55
|
+
@options[:editable] ||= {}
|
56
|
+
@options[:properties] ||= []
|
57
|
+
self.instance_eval(&block) if block
|
58
|
+
end
|
59
|
+
|
60
|
+
def keys
|
61
|
+
@options[:properties]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Implement the Model#labels method in terms of the
|
65
|
+
# template definition
|
66
|
+
|
67
|
+
def labels
|
68
|
+
@labels
|
69
|
+
end
|
70
|
+
|
71
|
+
# Implement the Model#is_editable? method in terms of the
|
72
|
+
# template definition. If the template doesn't further
|
73
|
+
# restrict the behavior, the model's definition is used
|
74
|
+
# instead.
|
75
|
+
|
76
|
+
def is_editable?(key)
|
77
|
+
k = key.to_sym
|
78
|
+
if @options[:editable].has_key? k
|
79
|
+
@options[:editable][k]
|
80
|
+
else
|
81
|
+
true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# This method is used to mark a property key editable or
|
86
|
+
# not through the view. This method does not impact the
|
87
|
+
# editability of the underlying model
|
88
|
+
|
89
|
+
def editable(key, val = true)
|
90
|
+
@options[:editable][key.to_sym] = val
|
91
|
+
end
|
92
|
+
|
93
|
+
# This method is used to mark a property visible or not
|
94
|
+
# through the view.
|
95
|
+
|
96
|
+
def property(key, options = {})
|
97
|
+
puts "options: #{options.inspect}"
|
98
|
+
key = key.to_sym
|
99
|
+
|
100
|
+
if false == options[:show]
|
101
|
+
show = false
|
102
|
+
else
|
103
|
+
show = true
|
104
|
+
end
|
105
|
+
|
106
|
+
editable(key, false) if false == options[:editable]
|
107
|
+
|
108
|
+
if show && !@options[:properties].include?(key)
|
109
|
+
@options[:properties] << key
|
110
|
+
l = options[:alias] || key.to_s.capitalize
|
111
|
+
@labels << options.merge({ :key => key, :label => l })
|
112
|
+
elsif !show
|
113
|
+
@options[:properties].delete(key)
|
114
|
+
@labels.delete_if do |k|
|
115
|
+
k[:key] == key
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# This method is used to apply the template to a specific,
|
121
|
+
# concrete model instance, creating a clone of the
|
122
|
+
# template in the process so that multiple different
|
123
|
+
# models can be used with the same template definition.
|
124
|
+
|
125
|
+
def apply(model)
|
126
|
+
@model = model
|
127
|
+
self.clone
|
128
|
+
end
|
129
|
+
|
130
|
+
def method_missing(m, *args, &block)
|
131
|
+
if @model
|
132
|
+
@model.send(m, *args, &block)
|
133
|
+
else
|
134
|
+
super
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|