自定义表单助手

有没有办法可以创建自定义表单助手,而不是:

special_field_tag :object, :method 

我可以实现以下目标:

 form.special_field :method 

是的,您可以添加到FormBuilder类并访问传递给form_for的对象。 我已经做了很多事情:日期,时间,测量等。下面是一个例子:

 class ActionView::Helpers::FormBuilder include ActionView::Helpers::TagHelper include ActionView::Helpers::FormTagHelper include ActionView::Helpers::FormOptionsHelper include ActionView::Helpers::CaptureHelper include ActionView::Helpers::AssetTagHelper # Accepts an int and displays a smiley based on >, <, or = 0 def smile_tag(method, options = {}) value = @object.nil? ? 0 : @object.send(method).to_i options[:id] = field_id(method,options[:index]) smiley = ":-|" if value > 0 smiley = ":-)" elsif smiley < 0 smiley = ":-(" end return text_field_tag(field_name(method,options[:index]),options) + smiley end def field_name(label,index=nil) output = index ? "[#{index}]" : '' return @object_name + output + "[#{label}]" end def field_id(label,index=nil) output = index ? "_#{index}" : '' return @object_name + output + "_#{label}" end end 

您可以这样使用:

 <% form_for @quiz do |f| %> <%= f.smile_tag(:score) %> <% end %> 

您可以在这些帮助程序方法中访问由Rails创建的一些实例变量:

  • @object - 表单指定的模型对象
  • @object_name - 对象的类名
  • @template - 我认为它是ActionView的一个实例,你可以绕过我在模板上调用方法添加的所有包含。 还没有尝试过。
  • @options - 由form_for调用创建的选项传递给FormBuilder

我编写了field_id和field_name方法来在HTML输入元素上创建这些属性,就像常规帮助程序一样,我确信有一种方法可以绑定到Rails使用的相同方法,但我还没有找到它。

天空是你可以用这些辅助方法做什么的限制,它们只是返回字符串。 您可以在一个中创建整个HTML表格或页面,但您最好有充分的理由。

该文件应添加到app / helpers文件夹中

@Tilendor,非常感谢指针。 下面是一个enum_select表单标记助手的示例,它使用Rails 4.1枚举自动填充选择标记的选项:

 # helpers/application_helper.rb module ApplicationHelper class ActionView::Helpers::FormBuilder # http://stackoverflow.com/a/2625727/1935918 include ActionView::Helpers::FormTagHelper include ActionView::Helpers::FormOptionsHelper def enum_select(name, options = {}) # select_tag "company[time_zone]", options_for_select(Company.time_zones # .map { |value| [value[0].titleize, value[0]] }, selected: company.time_zone) select_tag @object_name + "[#{name}]", options_for_select(@object.class.send(name.to_s.pluralize) .map { |value| [value[0].titleize, value[0]] }, selected: @object.send(name)) end end end 

@object.class.send(name.to_s.pluralize)构造是@object.class.send(name.to_s.pluralize) ,它产生可用值的散列(例如, Company.time_zones )。 将它放在helpers/application_helper.rb会使其自动可用。 它用作:

 <%= f.label :billing_status %>: <%= f.enum_select :billing_status %>

我们的应用程序在文本字段中显示电话号码,我们想省略国内号码的国家/地区代码。 我正在使用表单助手。 在阅读了这个和rails源之后,我找到了这个解决方案:

 class ActionView::Helpers::FormBuilder def phone_text_field name, options = {} value = object.public_send(name).to_s if value.start_with? "9" # national number value = value[1..-1] options["value"] = value end text_field name, options end end 

我把它放在app / helpers / application_helper.rb上并像使用text_field()帮助器一样使用它。 希望这有助于某人。