Rails 4 中的嵌套表单似乎不起作用
nested forms in Rails 4 doesn't seem to work
我关注这个已经太久了,所以开始吧。
- 尝试做一个简单的嵌套表单(在 Rails 3 中 多次 之前做过)但我似乎无法让嵌套字段呈现在 HTML.
- 如您所见,我正在尝试使用
3.times { @collection.collections_components.build }
构建 3 'collection components'(我的模型)。我确实得到了一个字段,但 3.times
被忽略了。
- 似乎
f.fields_for :collection_components
被忽略了。可以改成f.fields_for :xyz
,执行同一个字段。
在此处关注:http://guides.rubyonrails.org/form_helpers.html#nested-forms
这是一些代码:
collection.rb
class Collection < ActiveRecord::Base
has_many :collections_components, dependent: :destroy
accepts_nested_attributes_for :collections_components, allow_destroy: true
end
collections_component.rb
class CollectionsComponent < ActiveRecord::Base
belongs_to :collection
end
_form.html.erb
<%= form_for @collection do |f| %>
<% if @collection.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@collection.errors.count, "error") %> prohibited this collection from being saved:</h2>
<ul>
<% @collection.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<%= f.fields_for :collection_components do |collection_components_form| %>
<h2>Collection</h2>
<%= collection_components_form.label :text %>
<%= collection_components_form.text_field :text %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
collections_controller.rb
class CollectionsController < ApplicationController
before_action :set_collection, only: [:show, :edit, :update, :destroy]
def index
@collections = Collection.all
end
def show
end
def new
@collection = Collection.new
3.times { @collection.collections_components.build }
end
def edit
end
def create
@collection = Collection.new(collection_params)
respond_to do |format|
if @collection.save
format.html { redirect_to @collection, notice: 'Collection was successfully created.' }
format.json { render :show, status: :created, location: @collection }
else
format.html { render :new }
format.json { render json: @collection.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @collection.update(collection_params)
format.html { redirect_to @collection, notice: 'Collection was successfully updated.' }
format.json { render :show, status: :ok, location: @collection }
else
format.html { render :edit }
format.json { render json: @collection.errors, status: :unprocessable_entity }
end
end
end
def destroy
@collection.destroy
respond_to do |format|
format.html { redirect_to collections_url, notice: 'Collection was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_collection
@collection = Collection.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def collection_params
params.require(:collection).permit(:name, collections_components_attributes: [:text])
end
end
您需要显示所有 collections_components
的表格。变化:
<%= f.fields_for :collection_components do |collection_components_form| %>
<h2>Collection</h2>
<%= collection_components_form.label :text %>
<%= collection_components_form.text_field :text %>
<% end %>
至:
<% @collection.collection_components.each do |collections_component| %>
<%= f.fields_for :collection_components, collections_component do |collection_components_form| %>
<h2>Collection</h2>
<%= collection_components_form.hidden_field :id %>
<%= collection_components_form.label :text %>
<%= collection_components_form.text_field :text %>
<% end %>
<% end %>
id
的隐藏字段是更新所必需的。还要确保它包含在强参数中。
编辑:
我在使用 Rails 4.0.8 时遇到了这个问题。该版本的文档 suggests this solution with each
。 Rails 4.2.0 的文档开始建议只使用 fields_for
。我怀疑 fields_for
在 4.2.0 中直接开始处理集合,尽管我找不到它的任何更改日志。
我认为这可能是问题所在,您在 _form 中将资源称为单数而不是复数(在集合名称的中间)
<%= f.fields_for :collection_components do |collection_components_form| %>
而不是这个:
<%= f.fields_for :collections_components do |collection_components_form| %>
也就像我一直在使用 nested_forms 之前我知道你需要传递 "id" 并且只有当你允许销毁属性时才将“_destroy”参数传递给 strong_parameters,所以你加上它就好了
def collection_params
params.require(:collection).permit(:name, collections_components_attributes: [:text])
end
所以你应该有这样的东西:
def collection_params
params.require(:collection).permit(:name, {collections_components_attributes: [:id, :text, :_destroy]})
end
另外我会推荐这个 railscasts for future research and an excelent gem called cocoon 来轻松 [=28=]
希望对您有所帮助!
我关注这个已经太久了,所以开始吧。
- 尝试做一个简单的嵌套表单(在 Rails 3 中 多次 之前做过)但我似乎无法让嵌套字段呈现在 HTML.
- 如您所见,我正在尝试使用
3.times { @collection.collections_components.build }
构建 3 'collection components'(我的模型)。我确实得到了一个字段,但3.times
被忽略了。 - 似乎
f.fields_for :collection_components
被忽略了。可以改成f.fields_for :xyz
,执行同一个字段。
在此处关注:http://guides.rubyonrails.org/form_helpers.html#nested-forms
这是一些代码:
collection.rb
class Collection < ActiveRecord::Base
has_many :collections_components, dependent: :destroy
accepts_nested_attributes_for :collections_components, allow_destroy: true
end
collections_component.rb
class CollectionsComponent < ActiveRecord::Base
belongs_to :collection
end
_form.html.erb
<%= form_for @collection do |f| %>
<% if @collection.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@collection.errors.count, "error") %> prohibited this collection from being saved:</h2>
<ul>
<% @collection.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<%= f.fields_for :collection_components do |collection_components_form| %>
<h2>Collection</h2>
<%= collection_components_form.label :text %>
<%= collection_components_form.text_field :text %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
collections_controller.rb
class CollectionsController < ApplicationController
before_action :set_collection, only: [:show, :edit, :update, :destroy]
def index
@collections = Collection.all
end
def show
end
def new
@collection = Collection.new
3.times { @collection.collections_components.build }
end
def edit
end
def create
@collection = Collection.new(collection_params)
respond_to do |format|
if @collection.save
format.html { redirect_to @collection, notice: 'Collection was successfully created.' }
format.json { render :show, status: :created, location: @collection }
else
format.html { render :new }
format.json { render json: @collection.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @collection.update(collection_params)
format.html { redirect_to @collection, notice: 'Collection was successfully updated.' }
format.json { render :show, status: :ok, location: @collection }
else
format.html { render :edit }
format.json { render json: @collection.errors, status: :unprocessable_entity }
end
end
end
def destroy
@collection.destroy
respond_to do |format|
format.html { redirect_to collections_url, notice: 'Collection was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_collection
@collection = Collection.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def collection_params
params.require(:collection).permit(:name, collections_components_attributes: [:text])
end
end
您需要显示所有 collections_components
的表格。变化:
<%= f.fields_for :collection_components do |collection_components_form| %>
<h2>Collection</h2>
<%= collection_components_form.label :text %>
<%= collection_components_form.text_field :text %>
<% end %>
至:
<% @collection.collection_components.each do |collections_component| %>
<%= f.fields_for :collection_components, collections_component do |collection_components_form| %>
<h2>Collection</h2>
<%= collection_components_form.hidden_field :id %>
<%= collection_components_form.label :text %>
<%= collection_components_form.text_field :text %>
<% end %>
<% end %>
id
的隐藏字段是更新所必需的。还要确保它包含在强参数中。
编辑:
我在使用 Rails 4.0.8 时遇到了这个问题。该版本的文档 suggests this solution with each
。 Rails 4.2.0 的文档开始建议只使用 fields_for
。我怀疑 fields_for
在 4.2.0 中直接开始处理集合,尽管我找不到它的任何更改日志。
我认为这可能是问题所在,您在 _form 中将资源称为单数而不是复数(在集合名称的中间)
<%= f.fields_for :collection_components do |collection_components_form| %>
而不是这个:
<%= f.fields_for :collections_components do |collection_components_form| %>
也就像我一直在使用 nested_forms 之前我知道你需要传递 "id" 并且只有当你允许销毁属性时才将“_destroy”参数传递给 strong_parameters,所以你加上它就好了
def collection_params
params.require(:collection).permit(:name, collections_components_attributes: [:text])
end
所以你应该有这样的东西:
def collection_params
params.require(:collection).permit(:name, {collections_components_attributes: [:id, :text, :_destroy]})
end
另外我会推荐这个 railscasts for future research and an excelent gem called cocoon 来轻松 [=28=]
希望对您有所帮助!