自定义表单助手

24 ruby forms ruby-on-rails helpers

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

special_field_tag :object, :method
Run Code Online (Sandbox Code Playgroud)

我可以实现以下目标:

form.special_field :method
Run Code Online (Sandbox Code Playgroud)

Til*_*dor 48

是的,您可以添加到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
Run Code Online (Sandbox Code Playgroud)

您可以这样使用:

<% form_for @quiz do |f| %>
  <%= f.smile_tag(:score) %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

  • 您还可以继承FormBuilder,然后在每个表单的基础上使用自定义构建器:<%form_for @person,:builder => MyFormBuilder do | f | %> ... <%end%> (3认同)
  • 似乎这不会自动包含在内,您如何包含此内容? (3认同)

Dan*_*ohn 7

@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
Run Code Online (Sandbox Code Playgroud)

最棘手的构造是@object.class.send(name.to_s.pluralize)产生可用值的散列(例如Company.time_zones).放入helpers/application_helper.rb它使它自动可用.它用作:

<%= f.label :billing_status %>:
<%= f.enum_select :billing_status %><br />
Run Code Online (Sandbox Code Playgroud)