我做过类似的事情。我们使用自定义表单构建器格式化时间和长度。它利用现有的 text_field,但将其包装起来以便可以自定义值:
class SuperFormBuilder < ActionView::Helpers::FormBuilder
include ApplicationHelper
include FormHelper
include ActionView::Helpers::TagHelper
include ActionView::Helpers::FormTagHelper
def length_field(label,*args)
scale = 'medium'
args.each do |v|
if v.has_key?(:scale)
scale = v[:scale]
v.delete(:scale)
end
end
value = length_conversion(@object.send(label.to_sym),scale)
options = (args.length > 0) ? args.pop : {}
return has_error(label, text_field_tag(field_name(label),value,*args) + ' ' + length_unit(scale))
end
private
def field_name(label)
return @object_name + "[#{label}]"
end
def has_error(label, output)
return "<div class='fieldWithErrors'>#{output}</div>" if @object.errors[label]
return output
end
它是这样使用的:
<%= form_for( @section, {:action => 'save', :id => @section.id}, :builder => SuperFormBuilder) do |sf| %>
<%= sf.length_field :feed_size_min_w, :size => 3, :scale => 'small' %>
<% end %>
最终结果是根据他们对系统(公制、英制)和比例 IE small = 英寸或毫米的选择,采用适当单位的值。
我基本上从现有的表单构建器中复制了 text_field 方法,它使用了 text_field_tag 本身。
有两个陷阱:1)知道对象字段的名称以及如何访问对象以获取要格式化的值。 2) 获取正确的名称,以便在提交表单时它是正确参数哈希的一部分。
表单生成器被赋予一个类变量@object。您可以使用 .send 方法获取字段的值。在我的情况下,我将标签 :feed_size_min_w 发送到 @object 并取回它的长度。然后我将其转换为我想要的格式,并将其提供给 text_field_tag。
字段的名称是让它最终出现在 params 哈希中的关键,在我的例子中是 params[:sections] 之一。我创建了一个名为 field_name 的小辅助函数来处理这个问题。
最后,如果标签上有错误,has_error 会将字段包装在错误 div 中。