跳至内容 跳至搜索

Action View 表单生成器

FormBuilder 对象与特定模型对象关联,允许生成与模型对象关联的字段。使用 form_forfields_for 时会生成 FormBuilder 对象。例如

<%= form_for @person do |person_form| %>
  Name: <%= person_form.text_field :name %>
  Admin: <%= person_form.check_box :admin %>
<% end %>

在上述代码块中,FormBuilder 对象作为 person_form 变量生成。这允许通过指定同名方法来生成 text_fieldcheck_box 字段,这些方法修改底层模板并将 @person 模型对象与表单关联。

可以将 FormBuilder 对象视为 FormHelper 模块中方法的代理。但是,此类允许使用要为其构建表单的模型对象调用方法。

可以通过对该类进行子类化来创建自己的自定义 FormBuilder 模板。例如

class MyFormBuilder < ActionView::Helpers::FormBuilder
  def div_radio_button(method, tag_value, options = {})
    @template.content_tag(:div,
      @template.radio_button(
        @object_name, method, tag_value, objectify_options(options)
      )
    )
  end
end

上述代码创建了一个新方法 div_radio_button,该方法将一个 div 包装在新单选按钮周围。请注意,传入选项时,必须调用 objectify_options 才能将模型对象正确传递给该方法。如果未调用 objectify_options,则新创建的帮助器将不会链接回模型。

现在可以按如下方式使用上述 div_radio_button 代码

<%= form_for @person, :builder => MyFormBuilder do |f| %>
  I am a child: <%= f.div_radio_button(:admin, "child") %>
  I am an adult: <%= f.div_radio_button(:admin, "adult") %>
<% end -%>

用于表单构建的标准帮助器方法集位于 field_helpers 类属性中。

方法
#
B
C
D
E
F
G
H
I
L
M
N
P
R
S
T
U
W

属性

[R] 索引
[R] multipart
[R] multipart?
[RW] object
[RW] object_name
[RW] options

类公共方法

_to_partial_path()

# File actionview/lib/action_view/helpers/form_helper.rb, line 1703
def self._to_partial_path
  @_to_partial_path ||= name.demodulize.underscore.sub!(/_builder$/, "")
end

new(object_name, object, template, options)

# File actionview/lib/action_view/helpers/form_helper.rb, line 1715
def initialize(object_name, object, template, options)
  @nested_child_index = {}
  @object_name, @object, @template, @options = object_name, object, template, options
  @default_options = @options ? @options.slice(:index, :namespace, :skip_default_ids, :allow_method_names_outside_object) : {}
  @default_html_options = @default_options.except(:skip_default_ids, :allow_method_names_outside_object)

  convert_to_legacy_options(@options)

  if @object_name&.end_with?("[]")
    if (object ||= @template.instance_variable_get("@#{@object_name[0..-3]}")) && object.respond_to?(:to_param)
      @auto_index = object.to_param
    else
      raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
    end
  end

  @multipart = nil
  @index = options[:index] || options[:child_index]
end

实例公共方法

button(value = nil, options = {}, &block)

添加给定表单的提交按钮。当没有给定值时,它将检查对象是否为新资源,以创建正确的标签

<%= form_for @post do |f| %>
  <%= f.button %>
<% end %>

在上面的示例中,如果 @post 是新记录,它将使用 “创建帖子” 作为按钮标签;否则,它将使用 “更新帖子”。

这些标签可以使用 helpers.submit 键下的 I18n 进行自定义(与 submit 帮助器相同),并使用 %{model} 进行翻译插值

en:
  helpers:
    submit:
      create: "Create a %{model}"
      update: "Confirm changes to %{model}"

它还搜索特定于给定对象的键

en:
  helpers:
    submit:
      post:
        create: "Add %{model}"

示例

button("Create post")
# => <button name='button' type='submit'>Create post</button>

button(:draft, value: true)
# => <button id="post_draft" name="post[draft]" value="true" type="submit">Create post</button>

button do
  content_tag(:strong, 'Ask me!')
end
# => <button name='button' type='submit'>
#      <strong>Ask me!</strong>
#    </button>

button do |text|
  content_tag(:strong, text)
end
# => <button name='button' type='submit'>
#      <strong>Create post</strong>
#    </button>

button(:draft, value: true) do
  content_tag(:strong, "Save as draft")
end
# =>  <button id="post_draft" name="post[draft]" value="true" type="submit">
#       <strong>Save as draft</strong>
#     </button>
# File actionview/lib/action_view/helpers/form_helper.rb, line 2644
def button(value = nil, options = {}, &block)
  case value
  when Hash
    value, options = nil, value
  when Symbol
    value, options = nil, { name: field_name(value), id: field_id(value) }.merge!(options.to_h)
  end
  value ||= submit_default_value

  if block_given?
    value = @template.capture { yield(value) }
  end

  formmethod = options[:formmethod]
  if formmethod.present? && !/post|get/i.match?(formmethod) && !options.key?(:name) && !options.key?(:value)
    options.merge! formmethod: :post, name: "_method", value: formmethod
  end

  @template.button_tag(value, options)
end

check_box(method, options = {}, checked_value = "1", unchecked_value = "0")

返回一个复选框标签,该标签专门用于访问分配给模板(由 object 标识)的对象上的指定属性(由 method 标识)。此对象必须是一个实例对象(@object),而不是一个本地对象。它的目的是让 method 返回一个整数,如果该整数大于零,则选中复选框。可以将输入标签上的其他选项作为哈希与 options 一起传递。checked_value 默认为 1,而默认 unchecked_value 设置为 0,这对于布尔值很方便。

选项

  • 可以传递任何标准的 HTML 标签属性,例如 :class

  • :checked - truefalse 强制复选框的状态为选中或未选中。

  • :include_hidden - 如果设置为 false,则不会生成下面描述的辅助隐藏字段。

陷阱

HTML 规范规定,未选中的复选框不会成功,因此 Web 浏览器不会发送它们。不幸的是,这引入了一个陷阱:如果 Invoice 模型具有 paid 标志,并且在编辑已支付发票的表单中,用户取消选中其复选框,则不会发送 paid 参数。因此,任何大规模赋值惯用语,例如

@invoice.update(params[:invoice])

将不会更新标志。

为了防止这种情况,帮助器会在每个复选框之前生成一个辅助隐藏字段。隐藏字段具有相同的名称,其属性模仿未选中的复选框。

这样,客户端要么只发送隐藏字段(表示复选框未选中),要么同时发送两个字段。由于 HTML 规范规定键/值对必须按照它们在表单中出现的顺序发送,并且参数提取获取查询字符串中任何重复键的最后一次出现,因此这适用于普通表单。

不幸的是,当复选框位于类似数组的参数中时,该解决方法不起作用,例如

<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %>
  <%= form.check_box :paid %>
  ...
<% end %>

因为参数名称重复正是 Rails 试图区分数组元素的原因。对于每个具有选中复选框的项目,您都会获得一个额外的幽灵项目,该项目仅具有该属性,分配给“0”。

在这种情况下,最好使用 check_box_tag 或使用哈希而不是数组。

示例

# Let's say that @post.validated? is 1:
check_box("validated")
# => <input name="post[validated]" type="hidden" value="0" />
#    <input checked="checked" type="checkbox" id="post_validated" name="post[validated]" value="1" />

# Let's say that @puppy.gooddog is "no":
check_box("gooddog", {}, "yes", "no")
# => <input name="puppy[gooddog]" type="hidden" value="no" />
#    <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />

# Let's say that @eula.accepted is "no":
check_box("accepted", { class: 'eula_check' }, "yes", "no")
# => <input name="eula[accepted]" type="hidden" value="no" />
#    <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 2468
def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
  @template.check_box(@object_name, method, objectify_options(options), checked_value, unchecked_value)
end

collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)

包装 ActionView::Helpers::FormOptionsHelper#collection_check_boxes 以用于表单构建器

<%= form_for @post do |f| %>
  <%= f.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial %>
  <%= f.submit %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_options_helper.rb, line 908
def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
  @template.collection_check_boxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
end

collection_radio_buttons(方法、集合、值方法、文本方法、选项 = {}、html_选项 = {},&块)

包装 ActionView::Helpers::FormOptionsHelper#collection_radio_buttons 以用于表单生成器

<%= form_for @post do |f| %>
  <%= f.collection_radio_buttons :author_id, Author.all, :id, :name_with_initial %>
  <%= f.submit %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_options_helper.rb, line 920
def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
  @template.collection_radio_buttons(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
end

collection_select(方法、集合、值方法、文本方法、选项 = {}、html_选项 = {})

包装 ActionView::Helpers::FormOptionsHelper#collection_select 以用于表单生成器

<%= form_for @post do |f| %>
  <%= f.collection_select :person_id, Author.all, :id, :name_with_initial, prompt: true %>
  <%= f.submit %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_options_helper.rb, line 860
def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
  @template.collection_select(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options))
end

color_field(方法、选项 = {})

包装 ActionView::Helpers::FormHelper#color_field 以用于表单生成器

<%= form_with model: @user do |f| %>
  <%= f.color_field :favorite_color %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1838
      

date_field(方法、选项 = {})

包装 ActionView::Helpers::FormHelper#date_field 以用于表单生成器

<%= form_with model: @user do |f| %>
  <%= f.date_field :born_on %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1890
      

date_select(方法、选项 = {}、html_选项 = {})

包装 ActionView::Helpers::DateHelper#date_select 以用于表单生成器

<%= form_for @person do |f| %>
  <%= f.date_select :birth_date %>
  <%= f.submit %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/date_helper.rb, line 1237
def date_select(method, options = {}, html_options = {})
  @template.date_select(@object_name, method, objectify_options(options), html_options)
end

datetime_field(方法、选项 = {})

包装 ActionView::Helpers::FormHelper#datetime_field 以用于表单生成器

<%= form_with model: @user do |f| %>
  <%= f.datetime_field :graduation_day %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1916
      

datetime_local_field(方法、选项 = {})

包装 ActionView::Helpers::FormHelper#datetime_local_field 以用于表单生成器

<%= form_with model: @user do |f| %>
  <%= f.datetime_local_field :graduation_day %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1929
      

datetime_select(method, options = {}, html_options = {})

包装 ActionView::Helpers::DateHelper#datetime_select 以用于表单构建器

<%= form_for @person do |f| %>
  <%= f.datetime_select :last_request_at %>
  <%= f.submit %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/date_helper.rb, line 1261
def datetime_select(method, options = {}, html_options = {})
  @template.datetime_select(@object_name, method, objectify_options(options), html_options)
end

email_field(method, options = {})

包装 ActionView::Helpers::FormHelper#email_field 以用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.email_field :address %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1981
      

field_id(method, *suffixes, namespace: @options[:namespace], index: @options[:index])

为给定字段生成 HTML id 属性值

返回 FormBuilder 为给定属性名称生成的属性值。

<%= form_for @post do |f| %>
  <%= f.label :title %>
  <%= f.text_field :title, aria: { describedby: f.field_id(:title, :error) } %>
  <%= tag.span("is blank", id: f.field_id(:title, :error) %>
<% end %>

在上面的示例中,FormBuilder#text_field 调用构建的 <input type="text"> 元素声明了一个 aria-describedby 属性,引用 <span> 元素,共享一个公共 id 根(在本例中为 post_title)。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1772
def field_id(method, *suffixes, namespace: @options[:namespace], index: @options[:index])
  @template.field_id(@object_name, method, *suffixes, namespace: namespace, index: index)
end

field_name(method, *methods, multiple: false, index: @options[:index])

为给定的名称和字段组合生成 HTML name 属性值

返回 FormBuilder 为给定属性名称生成的属性值。

<%= form_for @post do |f| %>
  <%= f.text_field :title, name: f.field_name(:title, :subtitle) %>
  <%# => <input type="text" name="post[title][subtitle]"> %>
<% end %>

<%= form_for @post do |f| %>
  <%= f.text_field :tag, name: f.field_name(:tag, multiple: true) %>
  <%# => <input type="text" name="post[tag][]"> %>
<% end %>
# File actionview/lib/action_view/helpers/form_helper.rb, line 1792
def field_name(method, *methods, multiple: false, index: @options[:index])
  object_name = @options.fetch(:as) { @object_name }

  @template.field_name(object_name, method, *methods, index: index, multiple: multiple)
end

fields(scope = nil, model: nil, **options, &block)

请参阅 ActionView::Helpers::FormHelper#fields 帮助器方法的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 2322
def fields(scope = nil, model: nil, **options, &block)
  options[:allow_method_names_outside_object] = true
  options[:skip_default_ids] = !FormHelper.form_with_generates_ids

  convert_to_legacy_options(options)

  fields_for(scope || model, model, options, &block)
end

fields_for(record_name, record_object = nil, fields_options = nil, &block)

在特定模型对象周围创建作用域,类似于 form_for,但不会创建表单标记本身。这使得 fields_for 适用于在同一表单中指定其他模型对象。

虽然 fields_for 的用法和目的是类似于 form_for,但其方法签名略有不同。与 form_for 一样,它会向块生成与特定模型对象关联的 FormBuilder 对象,并且允许在块中调用生成器上的方法来生成与模型对象关联的字段。字段可以通过两种方式反映模型对象 - 它们的命名方式(因此提交的值在控制器中的 params 哈希中显示的方式)以及首次显示包含字段的表单时显示的默认值。为了独立指定这两个特性,对象名称(由符号或字符串表示)和对象本身可以分别传递给方法 -

<%= form_for @person do |person_form| %>
  First name: <%= person_form.text_field :first_name %>
  Last name : <%= person_form.text_field :last_name %>

  <%= fields_for :permission, @person.permission do |permission_fields| %>
    Admin?  : <%= permission_fields.check_box :admin %>
  <% end %>

  <%= person_form.submit %>
<% end %>

在这种情况下,复选框字段将由具有 name 属性 permission[admin] 的 HTML input 标记表示,并且提交的值将作为 params[:permission][:admin] 出现在控制器中。如果 @person.permission 是具有属性 admin 的现有记录,则首次显示时复选框的初始状态将反映 @person.permission.admin 的值。

通常,可以通过仅将模型对象的名称传递给 fields_for 来简化此过程 -

<%= fields_for :permission do |permission_fields| %>
  Admin?: <%= permission_fields.check_box :admin %>
<% end %>

…在这种情况下,如果 :permission 也恰好是实例变量 @permission 的名称,则输入字段的初始状态将反映该变量的属性 @permission.admin 的值。

或者,你可以仅传递模型对象本身(如果第一个参数不是字符串或符号,则 fields_for 会意识到名称已省略) -

<%= fields_for @person.permission do |permission_fields| %>
  Admin?: <%= permission_fields.check_box :admin %>
<% end %>

并且 fields_for 将从模型对象的中派生出字段的所需名称,例如,如果 @person.permissionPermission 类,则字段仍将命名为 permission[admin]

注意:这也适用于 FormOptionsHelperDateHelper 中的方法,这些方法被设计为以对象为基础,例如 FormOptionsHelper#collection_selectDateHelper#datetime_select

fields_for 尝试智能处理参数,但如果同时提供了名称和值参数,并且提供的值具有选项 Hash 的形状,则可能会混淆。为了消除歧义,请显式传递一个选项 Hash,即使它为空。

<%= form_for @person do |person_form| %>
  ...
  <%= fields_for :permission, @person.permission, {} do |permission_fields| %>
    Admin?: <%= check_box_tag permission_fields.field_name(:admin), @person.permission[:admin] %>
  <% end %>
  ...
<% end %>

嵌套属性示例

当属于当前范围的对象具有某个属性的嵌套属性写入器时,fields_for 将为该属性生成一个新的范围。这允许您创建表单,用于一次设置或更改父对象及其关联的属性。

嵌套属性写入器是根据关联命名的普通 setter 方法。定义这些写入器的最常见方法是在模型定义中使用 accepts_nested_attributes_for 或通过定义具有适当名称的方法。例如:关联 :address 的属性写入器称为 address_attributes=

生成一对一或一对多样式的表单构建器取决于普通读取器方法返回的是单个对象还是数组对象。

一对一

考虑一个 Person 类,它从 address 读取器方法返回单个 Address,并响应 address_attributes= 写入器方法

class Person
  def address
    @address
  end

  def address_attributes=(attributes)
    # Process the attributes hash
  end
end

现在可以使用嵌套 fields_for 来使用此模型,如下所示

<%= form_for @person do |person_form| %>
  ...
  <%= person_form.fields_for :address do |address_fields| %>
    Street  : <%= address_fields.text_field :street %>
    Zip code: <%= address_fields.text_field :zip_code %>
  <% end %>
  ...
<% end %>

当 address 已经是 Person 上的关联时,您可以使用 accepts_nested_attributes_for 为您定义写入器方法

class Person < ActiveRecord::Base
  has_one :address
  accepts_nested_attributes_for :address
end

如果您想通过表单销毁关联的模型,则必须首先使用 accepts_nested_attributes_for:allow_destroy 选项启用它

class Person < ActiveRecord::Base
  has_one :address
  accepts_nested_attributes_for :address, allow_destroy: true
end

现在,当您使用具有 _destroy 参数的表单元素时,如果该值评估为 true,您将销毁关联的模型(例如 1、‘1’、true 或 ‘true’)

<%= form_for @person do |person_form| %>
  ...
  <%= person_form.fields_for :address do |address_fields| %>
    ...
    Delete: <%= address_fields.check_box :_destroy %>
  <% end %>
  ...
<% end %>

一对多

考虑一个 Person 类,它从 projects reader 方法返回一个 Project 实例的数组并响应 projects_attributes= writer 方法

class Person
  def projects
    [@project1, @project2]
  end

  def projects_attributes=(attributes)
    # Process the attributes hash
  end
end

请注意,projects_attributes= writer 方法实际上对于 fields_for 正确识别 :projects 作为集合以及在表单标记中设置正确的索引是必需的。

当 projects 已经是 Person 上的关联时,可以使用 accepts_nested_attributes_for 为你定义 writer 方法

class Person < ActiveRecord::Base
  has_many :projects
  accepts_nested_attributes_for :projects
end

此模型现在可以与嵌套的 fields_for 一起使用。传递给嵌套 fields_for 调用的块将针对集合中的每个实例重复

<%= form_for @person do |person_form| %>
  ...
  <%= person_form.fields_for :projects do |project_fields| %>
    <% if project_fields.object.active? %>
      Name: <%= project_fields.text_field :name %>
    <% end %>
  <% end %>
  ...
<% end %>

还可以指定要使用的实例

<%= form_for @person do |person_form| %>
  ...
  <% @person.projects.each do |project| %>
    <% if project.active? %>
      <%= person_form.fields_for :projects, project do |project_fields| %>
        Name: <%= project_fields.text_field :name %>
      <% end %>
    <% end %>
  <% end %>
  ...
<% end %>

或要使用的集合

<%= form_for @person do |person_form| %>
  ...
  <%= person_form.fields_for :projects, @active_projects do |project_fields| %>
    Name: <%= project_fields.text_field :name %>
  <% end %>
  ...
<% end %>

如果你想通过表单销毁任何关联的模型,则必须首先使用 accepts_nested_attributes_for:allow_destroy 选项启用它

class Person < ActiveRecord::Base
  has_many :projects
  accepts_nested_attributes_for :projects, allow_destroy: true
end

这将允许你通过为 _destroy 参数添加一个表单元素(其值评估为 true(例如 1、'1'、true 或 'true'))来指定要在属性哈希中销毁哪些模型

<%= form_for @person do |person_form| %>
  ...
  <%= person_form.fields_for :projects do |project_fields| %>
    Delete: <%= project_fields.check_box :_destroy %>
  <% end %>
  ...
<% end %>

使用集合时,你可能想知道数组中每个对象的索引。为此,可以在 FormBuilder 对象中使用 index 方法。

<%= form_for @person do |person_form| %>
  ...
  <%= person_form.fields_for :projects do |project_fields| %>
    Project #<%= project_fields.index %>
    ...
  <% end %>
  ...
<% end %>

请注意,fields_for 将自动生成一个隐藏字段来存储记录的 ID。在某些情况下,不需要此隐藏字段,你可以传递 include_id: false 以防止 fields_for 自动呈现它。

# File actionview/lib/action_view/helpers/form_helper.rb, line 2284
def fields_for(record_name, record_object = nil, fields_options = nil, &block)
  fields_options, record_object = record_object, nil if fields_options.nil? && record_object.is_a?(Hash) && record_object.extractable_options?
  fields_options ||= {}
  fields_options[:builder] ||= options[:builder]
  fields_options[:namespace] = options[:namespace]
  fields_options[:parent_builder] = self

  case record_name
  when String, Symbol
    if nested_attributes_association?(record_name)
      return fields_for_with_nested_attributes(record_name, record_object, fields_options, block)
    end
  else
    record_object = @template._object_for_form_builder(record_name)
    record_name   = model_name_from_record_or_class(record_object).param_key
  end

  object_name = @object_name
  index = if options.has_key?(:index)
    options[:index]
  elsif defined?(@auto_index)
    object_name = object_name.to_s.delete_suffix("[]")
    @auto_index
  end

  record_name = if index
    "#{object_name}[#{index}][#{record_name}]"
  elsif record_name.end_with?("[]")
    "#{object_name}[#{record_name[0..-3]}][#{record_object.id}]"
  else
    "#{object_name}[#{record_name}]"
  end
  fields_options[:child_index] = index

  @template.fields_for(record_name, record_object, fields_options, &block)
end

file_field(method, options = {})

返回一个文件上传输入标签,该标签专门用于访问分配给模板(由 object 标识)的对象上的指定属性(由 method 标识)。输入标签上的其他选项可以作为哈希与 options 一起传递。这些选项将作为 HTML 元素属性标记到 HTML 中,如所示示例中所示。

form_with 块内使用此方法将把封闭表单的编码设置为 multipart/form-data

选项

  • 为标签创建标准 HTML 属性。

  • :disabled - 如果设置为 true,用户将无法使用此输入。

  • :multiple - 如果设置为 true,*在大多数更新的浏览器中*,用户将被允许选择多个文件。

  • :include_hidden - 当 multiple: trueinclude_hidden: true 时,该字段将以一个值为空的 <input type="hidden"> 字段作为前缀,以支持提交一个空文件集合。由于如果您未指定 include_hiddeninclude_hidden 将默认为 config.active_storage.multiple_file_field_include_hidden,因此在传递 multiple: true 时,您需要传递 include_hidden: false 以防止提交一个空文件集合。

  • :accept - 如果设置为一个或多个 MIME 类型,则在选择文件时会向用户建议一个过滤器。您仍然需要设置模型验证。

示例

# Let's say that @user has avatar:
file_field(:avatar)
# => <input type="file" id="user_avatar" name="user[avatar]" />

# Let's say that @post has image:
file_field(:image, :multiple => true)
# => <input type="file" id="post_image" name="post[image][]" multiple="multiple" />

# Let's say that @post has attached:
file_field(:attached, accept: 'text/html')
# => <input accept="text/html" type="file" id="post_attached" name="post[attached]" />

# Let's say that @post has image:
file_field(:image, accept: 'image/png,image/gif,image/jpeg')
# => <input type="file" id="post_image" name="post[image]" accept="image/png,image/gif,image/jpeg" />

# Let's say that @attachment has file:
file_field(:file, class: 'file_input')
# => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 2551
def file_field(method, options = {})
  self.multipart = true
  @template.file_field(@object_name, method, objectify_options(options))
end

grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})

为表单构建器包装 ActionView::Helpers::FormOptionsHelper#grouped_collection_select

<%= form_for @city do |f| %>
  <%= f.grouped_collection_select :country_id, @continents, :countries, :name, :id, :name %>
  <%= f.submit %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_options_helper.rb, line 872
def grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
  @template.grouped_collection_select(@object_name, method, collection, group_method, group_label_method, option_key_method, option_value_method, objectify_options(options), @default_html_options.merge(html_options))
end

hidden_field(method, options = {})

返回一个隐藏的输入标签,该标签专门用于访问分配给模板的对象(由 object 标识)上的指定属性(由 method 标识)。输入标签上的其他选项可以作为哈希传递,其中包含 options。这些选项将作为 HTML 元素属性标记到 HTML 中,如所示示例中所示。

示例

# Let's say that @signup.pass_confirm returns true:
hidden_field(:pass_confirm)
# => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="true" />

# Let's say that @post.tag_list returns "blog, ruby":
hidden_field(:tag_list)
# => <input type="hidden" id="post_tag_list" name="post[tag_list]" value="blog, ruby" />

# Let's say that @user.token returns "abcde":
hidden_field(:token)
# => <input type="hidden" id="user_token" name="user[token]" value="abcde" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 2512
def hidden_field(method, options = {})
  @emitted_hidden_id = true if method == :id
  @template.hidden_field(@object_name, method, objectify_options(options))
end

id()

生成 HTML id 属性值。

返回 <form> 元素的 id 属性。

<%= form_for @post do |f| %>
  <%# ... %>

  <% content_for :sticky_footer do %>
    <%= form.button(form: f.id) %>
  <% end %>
<% end %>

在上面的示例中,:sticky_footer 内容区域将存在于 <form> 元素之外。通过声明 form HTML 属性,我们向浏览器暗示生成的 <button> 元素应作为 <form> 元素的提交按钮,无论它在 DOM 中存在于何处。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1752
def id
  options.dig(:html, :id) || options[:id]
end

label(method, text = nil, options = {}, &block)

返回一个标签标记,该标记专用于标记分配给模板(由 object 标识)的对象上指定属性(由 method 标识)的输入字段。标签的文本将默认为属性名称,除非在当前 I18n 语言环境中找到翻译(通过 helpers.label.<modelname>.<attribute>)或您明确指定它。标签标记上的其他选项可以作为哈希与 options 一起传递。这些选项将作为 HTML 元素属性标记到 HTML 中,如所示示例,但 :value 选项除外,该选项旨在针对 radio_button 标记的标签(其中值用于输入标记的 ID)。

示例

label(:title)
# => <label for="post_title">Title</label>

您可以根据模型和属性名称本地化标签。例如,您可以在语言环境(例如 en.yml)中定义以下内容

helpers:
  label:
    post:
      body: "Write your entire text here"

然后将导致

label(:body)
# => <label for="post_body">Write your entire text here</label>

本地化也可以完全基于属性名称的翻译(如果您正在使用 ActiveRecord

activerecord:
  attributes:
    post:
      cost: "Total cost"

label(:cost)
# => <label for="post_cost">Total cost</label>

label(:title, "A short title")
# => <label for="post_title">A short title</label>

label(:title, "A short title", class: "title_label")
# => <label for="post_title" class="title_label">A short title</label>

label(:privacy, "Public Post", value: "public")
# => <label for="post_privacy_public">Public Post</label>

label(:cost) do |translation|
  content_tag(:span, translation, class: "cost_label")
end
# => <label for="post_cost"><span class="cost_label">Total cost</span></label>

label(:cost) do |builder|
  content_tag(:span, builder.translation, class: "cost_label")
end
# => <label for="post_cost"><span class="cost_label">Total cost</span></label>

label(:cost) do |builder|
  content_tag(:span, builder.translation, class: [
    "cost_label",
    ("error_label" if builder.object.errors.include?(:cost))
  ])
end
# => <label for="post_cost"><span class="cost_label error_label">Total cost</span></label>

label(:terms) do
  raw('Accept <a href="/terms">Terms</a>.')
end
# => <label for="post_terms">Accept <a href="/terms">Terms</a>.</label>
# File actionview/lib/action_view/helpers/form_helper.rb, line 2399
def label(method, text = nil, options = {}, &block)
  @template.label(@object_name, method, text, objectify_options(options), &block)
end

month_field(method, options = {})

包装 ActionView::Helpers::FormHelper#month_field 以用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.month_field :birthday_month %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1942
      

multipart=(multipart)

# File actionview/lib/action_view/helpers/form_helper.rb, line 1695
def multipart=(multipart)
  @multipart = multipart

  if parent_builder = @options[:parent_builder]
    parent_builder.multipart = multipart
  end
end

number_field(method, options = {})

包装 ActionView::Helpers::FormHelper#number_field 以用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.number_field :age %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1994
      

password_field(method, options = {})

包装 ActionView::Helpers::FormHelper#password_field 以用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.password_field :password %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1812
      

phone_field(method, options = {})

包装 ActionView::Helpers::FormHelper#phone_field 用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.phone_field :phone %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1877
      

radio_button(method, tag_value, options = {})

返回一个单选按钮标签,用于访问分配给模板的对象(由 object 标识)上的指定属性(由 method 标识)。如果 method 的当前值是 tag_value,则单选按钮将被选中。

要强制选中单选按钮,请在 options 哈希中传递 checked: true。您也可以在那里传递 HTML 选项。

# Let's say that @post.category returns "rails":
radio_button("category", "rails")
radio_button("category", "java")
# => <input type="radio" id="post_category_rails" name="post[category]" value="rails" checked="checked" />
#    <input type="radio" id="post_category_java" name="post[category]" value="java" />

# Let's say that @user.receive_newsletter returns "no":
radio_button("receive_newsletter", "yes")
radio_button("receive_newsletter", "no")
# => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
#    <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 2490
def radio_button(method, tag_value, options = {})
  @template.radio_button(@object_name, method, tag_value, objectify_options(options))
end

range_field(method, options = {})

包装 ActionView::Helpers::FormHelper#range_field 用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.range_field :age %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 2007
      

rich_text_area(method, options = {})

包装 ActionView::Helpers::FormHelper#rich_text_area 用于表单构建器

<%= form_with model: @message do |f| %>
  <%= f.rich_text_area :content %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actiontext/app/helpers/action_text/tag_helper.rb, line 89
def rich_text_area(method, options = {})
  @template.rich_text_area(@object_name, method, objectify_options(options))
end

search_field(method, options = {})

包装 ActionView::Helpers::FormHelper#search_field 用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.search_field :name %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1851
      

select(method, choices = nil, options = {}, html_options = {}, &block)

包装 ActionView::Helpers::FormOptionsHelper#select 用于表单构建器

<%= form_for @post do |f| %>
  <%= f.select :person_id, Person.all.collect { |p| [ p.name, p.id ] }, include_blank: true %>
  <%= f.submit %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_options_helper.rb, line 848
def select(method, choices = nil, options = {}, html_options = {}, &block)
  @template.select(@object_name, method, choices, objectify_options(options), @default_html_options.merge(html_options), &block)
end

submit(value = nil, options = {})

添加给定表单的提交按钮。当没有给定值时,它将检查对象是否为新资源,以创建正确的标签

<%= form_for @post do |f| %>
  <%= f.submit %>
<% end %>

在上面的示例中,如果 @post 是一个新记录,它将使用“创建帖子”作为提交按钮标签;否则,它将使用“更新帖子”。

这些标签可以使用 helpers.submit 键下的 I18n 进行自定义,并使用 %{model} 进行翻译插值

en:
  helpers:
    submit:
      create: "Create a %{model}"
      update: "Confirm changes to %{model}"

它还搜索特定于给定对象的键

en:
  helpers:
    submit:
      post:
        create: "Add %{model}"
# File actionview/lib/action_view/helpers/form_helper.rb, line 2583
def submit(value = nil, options = {})
  value, options = nil, value if value.is_a?(Hash)
  value ||= submit_default_value
  @template.submit_tag(value, options)
end

telephone_field(method, options = {})

包装 ActionView::Helpers::FormHelper#telephone_field 用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.telephone_field :phone %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1864
      

text_area(method, options = {})

包装 ActionView::Helpers::FormHelper#text_area 用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.text_area :detail %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1825
      

text_field(method, options = {})

包装 ActionView::Helpers::FormHelper#text_field 用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.text_field :name %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1799
      

time_field(method, options = {})

包装 ActionView::Helpers::FormHelper#time_field 用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.time_field :born_at %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1903
      

time_select(method, options = {}, html_options = {})

包装 ActionView::Helpers::DateHelper#time_select 用于表单构建器

<%= form_for @race do |f| %>
  <%= f.time_select :average_lap %>
  <%= f.submit %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/date_helper.rb, line 1249
def time_select(method, options = {}, html_options = {})
  @template.time_select(@object_name, method, objectify_options(options), html_options)
end

time_zone_select(method, priority_zones = nil, options = {}, html_options = {})

包装 ActionView::Helpers::FormOptionsHelper#time_zone_select 以用于表单构建器

<%= form_for @user do |f| %>
  <%= f.time_zone_select :time_zone, nil, include_blank: true %>
  <%= f.submit %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_options_helper.rb, line 884
def time_zone_select(method, priority_zones = nil, options = {}, html_options = {})
  @template.time_zone_select(@object_name, method, priority_zones, objectify_options(options), @default_html_options.merge(html_options))
end

to_model()

# File actionview/lib/action_view/helpers/form_helper.rb, line 1711
def to_model
  self
end

to_partial_path()

# File actionview/lib/action_view/helpers/form_helper.rb, line 1707
def to_partial_path
  self.class._to_partial_path
end

url_field(method, options = {})

包装 ActionView::Helpers::FormHelper#url_field 以用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.url_field :homepage %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1968
      

week_field(method, options = {})

包装 ActionView::Helpers::FormHelper#week_field 以用于表单构建器

<%= form_with model: @user do |f| %>
  <%= f.week_field :birthday_week %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_helper.rb, line 1955
      

weekday_select(method, options = {}, html_options = {})

包装 ActionView::Helpers::FormOptionsHelper#weekday_select 以用于表单构建器

<%= form_for @user do |f| %>
  <%= f.weekday_select :weekday, include_blank: true %>
  <%= f.submit %>
<% end %>

有关详细信息,请参阅基本帮助器的文档。

# File actionview/lib/action_view/helpers/form_options_helper.rb, line 896
def weekday_select(method, options = {}, html_options = {})
  @template.weekday_select(@object_name, method, objectify_options(options), @default_html_options.merge(html_options))
end