Rails 4不更新嵌套属性 [英] Rails 4 NOT updating nested attributes

查看:110
本文介绍了Rails 4不更新嵌套属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:当我点击#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆