Rails 4不更新嵌套属性 [英] Rails 4 NOT updating nested attributes
问题描述
问题:当我点击#update
时,它们会在现有嵌套属性的顶部创建,而不是更新嵌套属性关联的features_controller.rb
Issue: Instead of updating nested attributes, they are being created on top of the existing nested attributes when I hit the #update
action of the associated features_controller.rb
可能的原因:我认为问题出在我对Rails的form_for
缺乏了解.我认为细分是在我看来,我如何呈现持久的嵌套属性和/或我如何无法指定嵌套属性的ID,导致它仅创建一个新的嵌套属性
Likely Cause: I think the problem lies in my lack of understanding in Rails' form_for
. I think the breakdown is in my views, how I render the persisting nested attributes, and/or how I fail to specify the nested attribute's id, causing it to simply create a new one
feature.rb
class Feature < ActiveRecord::Base
...
has_many :scenarios
accepts_nested_attributes_for :scenarios,
allow_destroy: true,
reject_if: :all_blank
...
end
features_controller.rb
def update
...
project = Project.find(params[:project_id])
@feature = Feature.find(params[:id])
if @feature.update_attributes(feature_params)
# checking feature_params looks good...
# feature_params['scenarios'] => { <correct object hash> }
redirect_to project
else
render :edit
end
end
...
private
def feature_params
params.require(:feature).permit(:title, :narrative, :price, :eta, scenarios_attributes[:description, :_destroy])
end
_form.html.haml(简体)
= form_for [@project, @feature] do |f|
...
- if @feature.new_record? -# if we are creating new feature
= f.fields_for :scenarios, @feature.scenarios.build do |builder|
= builder.label :description, "Scenario"
= builder.text_area :description, rows: "3", autocomplete: "off"
- else -# if we are editing an existing feature
= f.fields_for :scenarios do |builder|
= builder.label :description, "Scenario"
= builder.text_area :description, rows: "3", autocomplete: "off"
我敢肯定,有一种更好的方法可以实现if @feature.new_record?
检查.我还使用了一些Javascript钩子来创建动态的嵌套属性形式(我已经省略了这些形式),这些形式在很大程度上受到
I'm sure there's a nicer way to achieve the if @feature.new_record?
check. I'm also using a few Javascript hooks to create dynamic nested attribute forms (which I've left out), heavily influenced by Railscast #196 Nested Model Form (revised)
我很喜欢一个非常不错的 Rails-y 实现,可以处理这些嵌套形式.
I would love a really nice Rails-y implementation of dealing with these sorts of nested forms.
推荐答案
尝试将:id
添加到feature_params
方法的:scenario_attributes
部分.您只有描述字段和允许销毁的功能.
Try adding :id
to the :scenario_attributes
portion of your feature_params
method. You only have the description field and the ability to allow a destroy.
def feature_params
# added => before nested attributes
params.require(:feature).permit(:id, :title, :narrative, :price, :eta, scenarios_attributes => [:id, :description, :_destroy])
end
正如@vinodadhikary所建议的那样,您不再需要检查feature是否是新记录,因为Rails(特别是使用form_for
方法)将为您做到这一点.
As @vinodadhikary suggested, you no longer need to check if feature is a new record, since Rails, specifically using the form_for
method, will do that for you.
更新:
您无需在表单中定义if @feature.new_record? ... else
.使用form_for
时,Rails会注意这一点. Rails根据object.persisted?
检查操作是create
还是update
,因此,您可以将表单更新为:
You don't need to define if @feature.new_record? ... else
in your form. It will be taken care by Rails when you use form_for
. Rails checks if the action is going to be create
or update
based on object.persisted?
, so, you can update your form to:
= form_for [@project, @feature] do |f|
...
= f.fields_for :scenarios, @feature.scenarios.build do |builder|
= builder.label :description, "Scenario"
= builder.text_area :description, rows: "3", autocomplete: "off"
这篇关于Rails 4不更新嵌套属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!