跳至內容 跳至搜尋

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")

傳回一個核取方塊標籤,專門用於存取指定屬性(由 method 識別)在指派給範本的物件上(由 object 識別)。這個物件必須是實例物件 (@object),而不是區域物件。預計 method 會傳回整數,如果該整數大於零,則核取方塊會被勾選。輸入標籤上的其他選項可以傳遞為雜湊,並使用 optionschecked_value 預設為 1,而預設的 unchecked_value 設定為 0,這對於布林值來說很方便。

選項

  • 標籤的任何標準 HTML 屬性都可以傳入,例如 :class

  • :checked - truefalse 強制核取方塊的狀態為勾選或不勾選。

  • :include_hidden - 如果設為 false,將不會產生以下所述的輔助隱藏欄位。

陷阱

HTML 規範指出未勾選的核取方塊不成功,因此網路瀏覽器不會傳送它們。不幸的是,這引入了陷阱:如果 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(method, collection, value_method, text_method, options = {}, html_options = {}, &block)

包裝 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(method, collection, value_method, text_method, options = {}, html_options = {})

包裝 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(method, options = {})

包裝 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(method, options = {})

包裝 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(method, options = {}, html_options = {})

包裝 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(method, options = {})

包裝 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(method, options = {})

包裝 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 hash 中)以及當包含欄位的表單首次顯示時顯示的預設值。為了讓這兩個功能都能獨立指定,物件名稱(以符號或字串表示)和物件本身都可以分別傳遞給方法 -

<%= 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.permission 屬於 Permission 類別,則欄位仍會命名為 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 將會為該屬性產生新的範圍。這讓您可以建立表單,一次設定或變更父物件及其關聯的屬性。

巢狀屬性寫入器是依據關聯命名的正常設定器方法。定義這些寫入器最常見的方式,是在模型定義中使用 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 讀取器方法傳回 Project 實例的陣列,並回應 projects_attributes= 寫入器方法

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

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

請注意,projects_attributes= 寫入器方法實際上是 fields_for 正確辨識 :projects 為集合,以及在表單標記中設定正確索引所需要的。

當 projects 已是 Person 上的關聯時,您可以使用 accepts_nested_attributes_for 為您定義寫入器方法

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 %>

當使用集合時,您可能想知道陣列中每個物件的索引。為此目的,index 方法可在 FormBuilder 物件中使用。

<%= 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_hidden 會預設為 config.active_storage.multiple_file_field_include_hidden,如果你沒有指定 include_hidden,你需要傳遞 include_hidden: false,以防止在傳遞 multiple: true 時提交空的檔案集合。

  • :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 = {})

傳回一個隱藏的輸入標籤,用於存取指定屬性(由 method 識別)在指派給範本的物件(由 object 識別)。輸入標籤上的其他選項可以傳遞為雜湊,其中包含 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)

傳回一個標籤標籤,用於標記指定屬性(由 method 識別)的輸入欄位,該屬性在指派給範本(由 object 識別)的物件上。標籤的文字預設為屬性名稱,除非在目前的 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 = {})

傳回一個無線按鈕標籤,用於存取指定屬性(由 method 識別),該屬性位於指派給範本的物件上(由 object 識別)。如果 method 的目前值為 tag_value,無線按鈕將會被勾選。

若要強制勾選無線按鈕,請在 options hash 中傳入 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