ruby-on-rails – Rails 4不更新嵌套属性

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – Rails 4不更新嵌套属性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
问题:当我点击相关的features_controller.rb的#update操作时,不会更新嵌套属性,而是在现有的嵌套属性之上创建它们.

可能的原因:我认为问题在于我在Rails的form_for中缺乏理解.我认为细分在我的看法,我如何呈现持久的嵌套属性,和/或我如何无法指定嵌套属性的id,导致它只是创建一个新的

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(simplified)

= 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,autocomplete: "off"

我确定有一个更好的方式来实现if @ feature.new_record?检查.我也使用一些Javascript钩子来创建动态嵌套的属性表单(我已经遗漏了),受到了Railscast #196 Nested Model Form (revised)的很大影响

我会喜欢一个非常好的Rails-y实现来处理这些嵌套表单.

解决方法

尝试将:id添加到feature_params方法的:scenario_attributes部分.你只有描述字段和允许破坏的能力.
def feature_params
  # added => before nested attributes
  params.require(:feature).permit(:id,:title,scenarios_attributes => [:id,:description,:_destroy])
end

正如@vinodadhikary所建议的那样,您不再需要检查功能是否是新的记录,因为Rails,特别是使用form_for方法,将为您做到这一点.

更新:

你不需要定义@ feature.new_record? …你的形式当您使用form_for时,它将被Rails照顾. Rails会检查是否要根据object.persisted?创建或更新该操作,因此,您可以将表单更新为:

= form_for [@project,@feature] do |f|
  ...
  = f.fields_for :scenarios,@feature.scenarios.build do |builder|
    = builder.label :description,"Scenario"
    = builder.text_area :description,autocomplete: "off"

猜你在找的Ruby相关文章