Rails 4.1嵌套属性和字段用于获取未允许的参数而不保存

时间:2014-07-11 23:14:35

标签: nested-attributes strong-parameters fields-for ruby-on-rails-4.1

研究:Rails 4.0 beta, fields_for not accepting pluralized model_name in one-to-many associationRails 4 Nested Attributes with fields_for Don't Save to Database

首先,让我们解决最常见的问题:强参数的错误命名属性参数。我是正确的复数。

class AdultsController < ApplicationController
...
  def update
    authorize @user
    respond_to do |format|
      if @user.update_attributes(user_params)
        format.html { redirect_to unit_adult_path(@unit, @user), notice: "#{@user.full_name} was successfully updated." }
      else
        format.html { render action: 'edit' }
      end
    end
  end

  def user_params
    params.require(:adult).permit(:first_name, :last_name, phones_attributes: [])
  end
end

我的模型设置正确

class User < ActiveRecord::Base
  has_many :phones, dependent: :destroy
  accepts_nested_attributes_for :phones, allow_destroy: true, reject_if: proc { |a| a["number"].blank? }
end

class Phone < ActiveRecord::Base
  belongs_to :user, touch: true
end

视图

# adult/_form.html.haml
= bootstrap_form_for [@unit, @user] do |f|
  = f.text_field :first_name, control_col: 'col-md-4'
  = f.text_field :last_name, control_col: 'col-md-4'

  = f.fields_for :phones do |f_phone|
    = f_phone.form_group do
      = f_phone.select :kind, options_for_phones, hide_label: true, layout: :default
      = f_phone.phone_field :number, hide_label: true, layout: :default
      = f_phone.check_box :_destroy, label: 'remove'

但是,当我提交用户表单保存时

Started PATCH "/units/2/adults/1" for 127.0.0.1 at 2014-07-11 15:20:17 -0700
Processing by AdultsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"pDjDVSiEs5qqHLqnbxQMeGWDOUGvhXPPvgyRGmitmps=", "adult"=>{"first_name"=>"Karl", "last_name"=>"Smith", "phones_attributes"=>{"0"=>{"kind"=>"other", "number"=>"888.1212", "_destroy"=>"0", "id"=>"173"}, "1"=>{"kind"=>"mobile", "number"=>"888.1212", "_destroy"=>"0", "id"=>"174"}} }, "commit"=>"Update Adult", "unit_id"=>"2", "id"=>"1"}

Unpermitted parameters: phones_attributes

我不明白为什么强参数评估会拒绝嵌套数据。 看起来对我来说是正确的。

我注意到的一件事是&#34; phones_attributes&#34;的params数据。值是HASH而不是ARRAY。在user_params中,phones_attributes:[]看起来像是期待ARRAY。所以我把它变成了HASH。

  def user_params
    params.require(:adult).permit(:first_name, :last_name, phones_attributes: {})
  end

但现在我收到以下错误。

Unpermitted parameters: 0, 1

所以我尝试在&#34; phones_attributes&#34;中指定字段名称。阵列。

def user_params
    params.require(:adult).permit(:first_name, :last_name, phones_attributes: [:id, :kind, :number])
end

我还是得到了。

Unpermitted parameters: phones_attributes

我知道我必须遗漏一些小事,但我无法找到错误。

编辑:我的所有嵌套属性表单都不起作用。他们停止时不是100%确定,但之前工作的那些不再有效并且没有被修改过。

1 个答案:

答案 0 :(得分:1)

想出来了。我使用javascript来复制手机字段(种类,数量),以便输入一组新的输入。该脚本正在为字段ID的一部分添加非数字字符,这导致rails忽略所有提交的phone_attributes。

对于下一个出现的人......

fields_for呈现字段时,当提交的帖子数据转换为参数时,它将为每个输入名称索引唯一性。在下面的示例中,此数字字段

<input id="adult_phones_attributes_0_number" name="adult[phones_attributes][0][number]" type="tel" value="7773331111">
当转换为params

时,

会看起来像这样

"phones_attributes"=>{"0"=>{"number"=>"7773331111"}}

&#34; 0&#34;的哈希键来自fields_for创建的索引。它是&#34; [0]&#34;名称的一部分。

在过去的rails版本中,如果嵌套属性params散列键不是数字,则忽略k / v对。那么现在有了强大的参数(我猜测罪魁祸首),它将拒绝整个&#34; phones_attributes&#34;散列。

我的脚本正在复制输入字段,在html上执行正则表达式以更改&#34; [0]&#34;索引到一个随机数。但有时它会取代它的非数字字符。这导致了这个问题。