maiha-active_record_view 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +25 -0
- data/Rakefile +22 -0
- data/arv/properties/boolean +4 -0
- data/arv/properties/date +5 -0
- data/arv/properties/datetime +5 -0
- data/arv/properties/default +3 -0
- data/arv/properties/integer +6 -0
- data/arv/properties/string +4 -0
- data/arv/properties/text +7 -0
- data/arv/properties/time +5 -0
- data/arv/properties/timestamp +5 -0
- data/arv/property.erb +19 -0
- data/init.rb +0 -0
- data/install.rb +1 -0
- data/lib/active_record_view.rb +2 -0
- data/lib/active_record_view/controller.rb +9 -0
- data/lib/active_record_view/default_actions.rb +29 -0
- data/lib/active_record_view/engines.rb +68 -0
- data/lib/active_record_view/helper.rb +152 -0
- data/lib/active_record_view/record_identifier.rb +42 -0
- data/lib/active_record_view/render_arv.rb +51 -0
- data/lib/active_record_view/write_exception.rb +11 -0
- data/lib/localized/model.rb +103 -0
- data/lib/localized/view_property.rb +337 -0
- data/spec/fixtures/card.rb +12 -0
- data/spec/fixtures/card/equip.rb +13 -0
- data/spec/fixtures/card/magic.rb +13 -0
- data/spec/fixtures/card/member.rb +13 -0
- data/spec/fixtures/card/unit.rb +13 -0
- data/spec/fixtures/deck.rb +2 -0
- data/spec/localized/decks.yml +39 -0
- data/spec/migrate/001_create_cards.rb +16 -0
- data/spec/migrate/002_create_decks.rb +5 -0
- data/spec/models/active_record_view_helper_spec.rb +393 -0
- data/spec/models/render_spec.rb +220 -0
- data/spec/schema.rb +30 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +27 -0
- data/tasks/active_record_view_tasks.rake +37 -0
- data/test/active_record_view_test.rb +8 -0
- data/uninstall.rb +1 -0
- metadata +93 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
module ActiveRecordView
|
2
|
+
module RenderArv
|
3
|
+
def render(*args, &block)
|
4
|
+
options = args.first
|
5
|
+
if options.is_a?(Hash) and options[:arv]
|
6
|
+
arv = options.delete(:arv)
|
7
|
+
render_arv(arv, options)
|
8
|
+
else
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def render_arv(arv, options = {})
|
14
|
+
path, arv_name = partial_pieces(arv.to_s)
|
15
|
+
root = Pathname(RAILS_ROOT).cleanpath.to_s + "/"
|
16
|
+
file = "app/views/%s/%s.arv" % [path, arv_name]
|
17
|
+
rhtml = arv_erb_code(File.read(root + file), arv_name, options)
|
18
|
+
ActiveRecord::Base.logger.debug "Rendering %s" % file.inspect
|
19
|
+
render :inline=>rhtml
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def arv_erb_code(buffer, arv_name, options)
|
24
|
+
html = ''
|
25
|
+
array = buffer.scan(/^([^#]\S+?)\s*=(.*?)$/m)
|
26
|
+
names = array.map(&:first)
|
27
|
+
leads = array.map{|a| a.last.to_s.strip}
|
28
|
+
|
29
|
+
names.each_with_index do |name, i|
|
30
|
+
next if (lead = leads[i]).blank? and (i > 0)
|
31
|
+
colspan = 1 + (leads[i+1..-1].map(&:blank?)+[false]).index(false)
|
32
|
+
html << "<th class='%s' colspan=%d>%s</th>" % [name, colspan, lead]
|
33
|
+
end
|
34
|
+
options[:class] = "arv-list #{arv_name} #{options[:class]}".strip
|
35
|
+
content_tag(:table, <<-ERB, options)
|
36
|
+
<thead><tr>#{html}</tr></thead>
|
37
|
+
<%= collection_tbody_for(@#{arv_name}, %w( #{names.join(' ')} )) %>
|
38
|
+
ERB
|
39
|
+
end
|
40
|
+
|
41
|
+
# derived from Rails1.2 for Rails2.1
|
42
|
+
def partial_pieces(partial_path)
|
43
|
+
if partial_path.include?('/')
|
44
|
+
return File.dirname(partial_path), File.basename(partial_path)
|
45
|
+
else
|
46
|
+
return controller.class.controller_path, partial_path
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module ActiveRecordView::WriteException
|
2
|
+
def write_exception_logger
|
3
|
+
ActionController::Base.logger
|
4
|
+
end
|
5
|
+
|
6
|
+
def write_exception(error, size = 5)
|
7
|
+
user_backtrace = error.application_backtrace.reject{|i| i =~ %r{^\#\{RAILS_ROOT\}/vendor/}}
|
8
|
+
trace = user_backtrace[0,size - 1].join("\n")
|
9
|
+
write_exception_logger.error "%s: %s (%s)" % [error.class, error.message, trace]
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
class Localized::Model
|
2
|
+
attr_reader :yaml_path, :active_record
|
3
|
+
delegate :logger, :to=>"ActiveRecord::Base"
|
4
|
+
cattr_accessor :yaml_path
|
5
|
+
if defined?(RAILS_ROOT)
|
6
|
+
self.yaml_path = File.join(RAILS_ROOT, "db/localized")
|
7
|
+
end
|
8
|
+
|
9
|
+
class ConfigurationError < ActionView::ActionViewError; end
|
10
|
+
class << self
|
11
|
+
def [](model_name)
|
12
|
+
klass = active_record_class_for(model_name)
|
13
|
+
@localized_models ||= {}
|
14
|
+
@localized_models[klass.table_name] ||= new(klass)
|
15
|
+
end
|
16
|
+
|
17
|
+
def active_record_class_for(klass)
|
18
|
+
case klass
|
19
|
+
when Class
|
20
|
+
# nop
|
21
|
+
when ActiveRecord::Base
|
22
|
+
klass = klass.class
|
23
|
+
else
|
24
|
+
klass = klass.to_s.classify.constantize
|
25
|
+
end
|
26
|
+
|
27
|
+
klass.ancestors.include?(ActiveRecord::Base) or
|
28
|
+
raise ConfigurationError, "#{name}[] expects ActiveRecord class, but got #{klass.name}"
|
29
|
+
|
30
|
+
return klass
|
31
|
+
end
|
32
|
+
|
33
|
+
def human_value(record, column_name)
|
34
|
+
self[record.class].view_property(column_name).human_value(record[column_name])
|
35
|
+
end
|
36
|
+
|
37
|
+
def masters(model_name, column_name)
|
38
|
+
self[model_name].view_property(column_name).masters
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(active_record)
|
43
|
+
@active_record = active_record
|
44
|
+
@table_name = @active_record.table_name
|
45
|
+
@view_properties = {}
|
46
|
+
@yaml = YAML::load_file(absolute_yaml_path)
|
47
|
+
logger.debug("Loaded localized setting from '#{absolute_yaml_path}'")
|
48
|
+
rescue Errno::ENOENT
|
49
|
+
raise ConfigurationError, "Cannot read YAML data from #{absolute_yaml_path}.\nRun 'rake arv:create:view %s'" % @active_record
|
50
|
+
rescue ArgumentError => err
|
51
|
+
logger.debug("Localize Error: YAML #{err} in #{yaml_path}")
|
52
|
+
@load_error = true
|
53
|
+
end
|
54
|
+
|
55
|
+
def [] (group_name, attr_name = nil)
|
56
|
+
return nil if load_error?
|
57
|
+
localized_name = @yaml[group_name.to_s]
|
58
|
+
localized_name = localized_name[attr_name] if attr_name
|
59
|
+
return localized_name
|
60
|
+
rescue => err
|
61
|
+
logger.debug("Localize Error: for (%s,%s). %s" % [group_name, attr_name, err])
|
62
|
+
return nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def instance_name
|
66
|
+
self[:names][:instance]
|
67
|
+
end
|
68
|
+
|
69
|
+
def masters
|
70
|
+
pkey = active_record.primary_key
|
71
|
+
options = active_record.columns_hash[instance_name.to_s] && {:select=>"#{pkey},#{instance_name}"} || {}
|
72
|
+
active_record.find(:all, options.merge(:order=>pkey)).collect{|r| [r[pkey], localize_instance(r)]}
|
73
|
+
end
|
74
|
+
|
75
|
+
def localize_instance (record)
|
76
|
+
name = instance_name
|
77
|
+
case name
|
78
|
+
when NilClass ; return nil
|
79
|
+
when Symbol ; return record.send(name)
|
80
|
+
when String ; return name.gsub('%d', record.id.to_s)
|
81
|
+
else
|
82
|
+
raise TypeError, "got %s, expected Symbol or String. Check '%s'" % [name.class, yaml_path]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def load_error?
|
87
|
+
@load_error
|
88
|
+
end
|
89
|
+
|
90
|
+
def view_property(column_name)
|
91
|
+
@view_properties[column_name] ||= Localized::ViewProperty.new(self, column_name, self["property_#{column_name}"])
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
def absolute_yaml_path
|
96
|
+
@absolute_yaml_path ||= (Pathname(self.class.yaml_path) + yaml_path).cleanpath
|
97
|
+
end
|
98
|
+
|
99
|
+
def yaml_path
|
100
|
+
"#{@table_name}.yml"
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,337 @@
|
|
1
|
+
class Localized::ViewProperty
|
2
|
+
attr_reader :options, :model, :master_class, :column_name, :master_hash
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def [](model_name, column_name)
|
6
|
+
model = find_model(model_name)
|
7
|
+
if model
|
8
|
+
model.view_property(column_name)
|
9
|
+
else
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def find_model(name)
|
16
|
+
@cached_models ||= {}
|
17
|
+
case (model = @cached_models[name])
|
18
|
+
when :missing
|
19
|
+
return nil
|
20
|
+
when Localized::Model
|
21
|
+
return model
|
22
|
+
when NilClass
|
23
|
+
begin
|
24
|
+
return @cached_models[name] = Localized::Model[name]
|
25
|
+
rescue Localized::Model::ConfigurationError
|
26
|
+
@cached_models[name] = :missing
|
27
|
+
return nil
|
28
|
+
end
|
29
|
+
else
|
30
|
+
raise "[BUG] Localized::ViewProperty is broken! (cannot find model for #{name})"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(model, column_name, hash = nil)
|
36
|
+
hash ||= {}
|
37
|
+
|
38
|
+
@blank = true if hash.blank?
|
39
|
+
@model = model
|
40
|
+
@column_name = column_name
|
41
|
+
@yaml_data = hash
|
42
|
+
@options = hash[:options] || {}
|
43
|
+
@master_array = []
|
44
|
+
@master_hash = {}
|
45
|
+
@master_class = nil
|
46
|
+
|
47
|
+
parse_master
|
48
|
+
@include_blank = @master_array.first.first.to_s.empty? rescue false
|
49
|
+
end
|
50
|
+
|
51
|
+
def blank?
|
52
|
+
@blank
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
def parse_master
|
57
|
+
master = @yaml_data[:masters]
|
58
|
+
@master_array = []
|
59
|
+
@master_hash = {}
|
60
|
+
@master_class = nil
|
61
|
+
|
62
|
+
case master
|
63
|
+
when NilClass
|
64
|
+
when String
|
65
|
+
model = Localized::Model[master]
|
66
|
+
@master_class = model.active_record
|
67
|
+
@master_array = model.masters
|
68
|
+
@master_array.each do |key, val|
|
69
|
+
@master_hash[key] = val
|
70
|
+
end
|
71
|
+
when Array
|
72
|
+
master.each do |hash|
|
73
|
+
key, val = hash.to_a.first
|
74
|
+
@master_array << [key, val]
|
75
|
+
@master_hash[key] = val
|
76
|
+
end
|
77
|
+
else
|
78
|
+
raise Localized::Model::ConfigurationError,
|
79
|
+
"Cannot accept '%s' as master. It should be an Array or :belongs_to or a String(ActiveRecord class name). Check %s." % [master.class, @model.yaml_path]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
public
|
84
|
+
def [](key)
|
85
|
+
@yaml_data[key]
|
86
|
+
end
|
87
|
+
|
88
|
+
def masters
|
89
|
+
@master_array
|
90
|
+
end
|
91
|
+
|
92
|
+
def master(value)
|
93
|
+
@master_hash[value]
|
94
|
+
end
|
95
|
+
|
96
|
+
def reload_master
|
97
|
+
parse_master
|
98
|
+
return masters
|
99
|
+
end
|
100
|
+
|
101
|
+
def has_master?
|
102
|
+
not masters.empty?
|
103
|
+
end
|
104
|
+
|
105
|
+
def include_blank?
|
106
|
+
@include_blank
|
107
|
+
end
|
108
|
+
|
109
|
+
def has_time_format?
|
110
|
+
self[:time_format]
|
111
|
+
end
|
112
|
+
|
113
|
+
def has_format?(postfix = nil)
|
114
|
+
self["format#{postfix}".intern] || self[:format]
|
115
|
+
end
|
116
|
+
|
117
|
+
def has_column_type?
|
118
|
+
self[:column_type].is_a?(Symbol)
|
119
|
+
end
|
120
|
+
|
121
|
+
def column_type
|
122
|
+
(has_column_type? && self[:column_type]) || (has_master? && :master) || nil
|
123
|
+
end
|
124
|
+
|
125
|
+
def system_column_type
|
126
|
+
column = klass.columns_hash[column_name.to_s]
|
127
|
+
column ? column.type : nil
|
128
|
+
rescue
|
129
|
+
nil
|
130
|
+
end
|
131
|
+
|
132
|
+
def klass
|
133
|
+
model.active_record
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
# TODO: split to property model and rendering engine
|
138
|
+
include ActionView::Helpers::TagHelper # for content_tag
|
139
|
+
include ActionView::Helpers::FormHelper # for check_box
|
140
|
+
include ActionView::Helpers::FormTagHelper # for check_box_tag
|
141
|
+
|
142
|
+
|
143
|
+
######################################################################
|
144
|
+
### Rendering
|
145
|
+
|
146
|
+
def human_value (value, controller = nil)
|
147
|
+
controller &&= controller.is_a?(ActionController::Base) ? controller : controller.controller
|
148
|
+
|
149
|
+
case column_type
|
150
|
+
when :acts_as_bits
|
151
|
+
aab_names = klass.send("#{column_name.to_s.singularize}_names")
|
152
|
+
checkeds = Hash[*aab_names.zip(value.to_s.split(//)).flatten]
|
153
|
+
|
154
|
+
aab_masters = self.masters
|
155
|
+
aab_masters = klass.send("#{column_name.to_s.singularize}_names_with_labels") if aab_masters.blank?
|
156
|
+
|
157
|
+
type = :button
|
158
|
+
case type
|
159
|
+
when :button
|
160
|
+
lis = aab_masters.map{|(name, title)|
|
161
|
+
style = (checkeds[name].to_i == 1) ? "checked" : "unchecked"
|
162
|
+
span = content_tag(:span, title || name)
|
163
|
+
content_tag(:li, span, :class=>style)
|
164
|
+
}
|
165
|
+
return content_tag(:ul, lis.join(' '), :class=>"aab")
|
166
|
+
when :checkbox
|
167
|
+
options = (options||{}).merge(:disabled=>"disabled")
|
168
|
+
html = masters.map{|(name, title)|
|
169
|
+
check = check_box_tag("aab", 1, (checkeds[name].to_i==1), options)
|
170
|
+
label = h(title || name)
|
171
|
+
'<span style="white-space: nowrap;">%s %s</span>' % [check, label]
|
172
|
+
}.join(" ")
|
173
|
+
return html
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
if has_master?
|
178
|
+
html = master(value)
|
179
|
+
elsif has_time_format?
|
180
|
+
html = [Date, Time].include?(value.class) ? value.strftime(self[:time_format]) : ''
|
181
|
+
elsif controller && format = has_format?("_" + controller.action_name)
|
182
|
+
html = format % ERB::Util.html_escape(value)
|
183
|
+
elsif (column_type || system_column_type) == :text
|
184
|
+
html = ERB::Util.html_escape(value.strip.to_s).gsub(/\r?\n/,'<BR>')
|
185
|
+
else
|
186
|
+
html = ERB::Util.html_escape(value)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
def human_edit(singular_name, view, opts = {})
|
192
|
+
record = opts.delete(:record) || view.instance_variable_get("@#{singular_name}")
|
193
|
+
options = self.options.merge(opts)
|
194
|
+
options[:class] = "#{column_name} #{options[:class]}".strip
|
195
|
+
|
196
|
+
if time_format = has_time_format?
|
197
|
+
value = record.send(column_name)
|
198
|
+
if edit_format = has_format?("_edit")
|
199
|
+
return human_edit_time_text_field_with_format(view, edit_format, value, singular_name)
|
200
|
+
else
|
201
|
+
return human_edit_time_with_format(view, time_format, value, singular_name)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
case column_type
|
206
|
+
when :acts_as_bits
|
207
|
+
aab_masters = self.masters
|
208
|
+
aab_masters = klass.send("#{column_name.to_s.singularize}_names_with_labels") if aab_masters.blank?
|
209
|
+
|
210
|
+
html = aab_masters.map{|(name, title)|
|
211
|
+
check = view.check_box(singular_name, name, options) rescue "(#{name}?)"
|
212
|
+
label = view.send(:h, title || name)
|
213
|
+
label = view.send(:content_tag, :label, label, :for=>"#{singular_name}_#{name}")
|
214
|
+
'<span style="white-space: nowrap;">%s %s</span>' % [check, label]
|
215
|
+
}.join(" ")
|
216
|
+
when :acts_as_tree
|
217
|
+
value = record.send(column_name)
|
218
|
+
record = master_class.find(value) rescue nil
|
219
|
+
html = view.acts_as_tree_field(singular_name, column_name, master_class, record)
|
220
|
+
when :checkbox, :check_box
|
221
|
+
html = view.check_box(singular_name, column_name, options)
|
222
|
+
when :radio, :radio_button
|
223
|
+
separater = " "
|
224
|
+
delimiter = " "
|
225
|
+
html = masters.map{|key,val|
|
226
|
+
[
|
227
|
+
view.radio_button(singular_name, column_name, key, options).to_s,
|
228
|
+
# content_tag(:label, val.to_s, :for=>"#{singular_name}_#{column_name}_#{key}")
|
229
|
+
val.to_s
|
230
|
+
].join(separater)
|
231
|
+
} * delimiter
|
232
|
+
|
233
|
+
# add following line to your css to avoid blocked radio button in AR error
|
234
|
+
# div.fieldWithErrors .radio-group {border:1px solid #FF0000;}
|
235
|
+
# .radio-group div.fieldWithErrors {display : inline;}
|
236
|
+
|
237
|
+
html = content_tag :div, html, :class=>"radio-group"
|
238
|
+
html = content_tag :div, html, :class=>"fieldWithErrors" if record.errors.on(column_name)
|
239
|
+
|
240
|
+
when :master
|
241
|
+
html = view.collection_select(singular_name, column_name, masters, :first, :last, options)
|
242
|
+
when :time
|
243
|
+
tag = ActionView::Helpers::InstanceTag.new(singular_name, column_name, view)
|
244
|
+
html = tag.to_time_select_tag(options)
|
245
|
+
when NilClass
|
246
|
+
if system_column_type
|
247
|
+
tag = ActionView::Helpers::InstanceTag.new(singular_name, column_name, view, view, record)
|
248
|
+
html = tag.to_tag(options)
|
249
|
+
else
|
250
|
+
if view.respond_to?(column_name)
|
251
|
+
view.send(column_name, record)
|
252
|
+
else
|
253
|
+
view.text_field_tag "#{singular_name}[#{column_name}]", record[column_name]
|
254
|
+
end
|
255
|
+
end
|
256
|
+
else
|
257
|
+
tag = ActionView::Helpers::InstanceTag.new(singular_name, column_name, view, view, record)
|
258
|
+
tag.instance_eval("def column_type; :%s; end" % self[:column_type])
|
259
|
+
html = tag.to_tag(options)
|
260
|
+
end
|
261
|
+
|
262
|
+
# if format = has_format?("_" + view.controller.action_name)
|
263
|
+
# html = format % html
|
264
|
+
# end
|
265
|
+
|
266
|
+
return html
|
267
|
+
end
|
268
|
+
|
269
|
+
protected
|
270
|
+
def human_edit_time_with_format(view, time_format, value, singular_name)
|
271
|
+
used = Set.new
|
272
|
+
opts = Proc.new { |position|
|
273
|
+
used << position
|
274
|
+
options.merge(:prefix => singular_name, :field_name=>"#{column_name}(#{position}i)")}
|
275
|
+
|
276
|
+
html = time_format.gsub(/%([YmdHMS])/) do
|
277
|
+
case $1
|
278
|
+
when 'Y'; view.select_year(value, opts.call(1))
|
279
|
+
when 'm'; view.select_month(value, opts.call(2))
|
280
|
+
when 'd'; view.select_day(value, opts.call(3))
|
281
|
+
when 'H'; view.select_hour(value, opts.call(4))
|
282
|
+
when 'M'; view.select_minute(value, opts.call(5))
|
283
|
+
when 'S'; view.select_second(value, opts.call(6))
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
hidden = (1...used.min).map{|i|
|
288
|
+
name = "%s[%s]" % opts.call(i).values_at(:prefix, :field_name)
|
289
|
+
view.hidden_field_tag(name, 1)}.join
|
290
|
+
return hidden + html
|
291
|
+
end
|
292
|
+
|
293
|
+
def human_edit_time_text_field_with_format(view, time_format, value, singular_name)
|
294
|
+
used = Set.new
|
295
|
+
name = Proc.new { |position|
|
296
|
+
used << position
|
297
|
+
"%s[%s(%di)]" % [singular_name, column_name, position]}
|
298
|
+
time = Proc.new { |time_object, method, zero|
|
299
|
+
begin
|
300
|
+
val = time_object.__send__(method).to_i
|
301
|
+
val = "%02d" % val if zero
|
302
|
+
val
|
303
|
+
rescue
|
304
|
+
''
|
305
|
+
end
|
306
|
+
}
|
307
|
+
opts = proc {|*args| size, klass = args
|
308
|
+
hash = options.merge(:style=>"width:#{size}px;")
|
309
|
+
hash.merge!(:class=>"#{hash[:class]} #{klass}") if klass
|
310
|
+
hash
|
311
|
+
}
|
312
|
+
|
313
|
+
html = time_format.gsub(/%(0?)(\d*)([YmdHMS])/) do
|
314
|
+
zero = !$1.blank?
|
315
|
+
size = ($2.blank? ? 2 : $2).to_i*10+5
|
316
|
+
case $3
|
317
|
+
when 'Y'; view.text_field_tag(name.call(1), time.call(value,:year,zero), opts.call(size))
|
318
|
+
when 'm'; view.text_field_tag(name.call(2), time.call(value,:month,zero), opts.call(size))
|
319
|
+
when 'd'; view.text_field_tag(name.call(3), time.call(value,:day,zero), opts.call(size))
|
320
|
+
when 'H'; view.text_field_tag(name.call(4), time.call(value,:hour,zero), opts.call(size, "time-hour"))
|
321
|
+
when 'M'; view.text_field_tag(name.call(5), time.call(value,:min,zero), opts.call(size, "time-minute"))
|
322
|
+
when 'S'; view.text_field_tag(name.call(6), time.call(value,:sec,zero), opts.call(size))
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
hidden = (1...used.min).map{|i| view.hidden_field_tag(name.call(i), 1)}.join
|
327
|
+
return hidden + html
|
328
|
+
end
|
329
|
+
|
330
|
+
def configuration_error(message)
|
331
|
+
raise Localized::Model::ConfigurationError, "%s (check 'property_%s' in %s)" %
|
332
|
+
[message, column_name, model.yaml_path]
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
|
337
|
+
|