ruby_mvc 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|