繁体   English   中英

具有simple_form和强参数的嵌套表单

[英]Nested form with simple_form and strong parameters

带有has_many的嵌套has_many关联返回以下参数哈希:

params
# => {
       "user"=>{
         "first_name"=>"John",
         "last_name"=>"Doe",
         "bank_accounts_attributes"=>{
           "-1"=>{
             "_destroy"=>"0",
             "iban"=>"fakeiban",
             "bic"=>"fakebic"
           },
           "new-bank-account"=>{
             "_destroy"=>"0",
             "iban"=>"",
             "bic"=>""
           }
         }
       }
     }

密钥“ -1”是通过在DOM中复制“ new-bank-account”模板而创建的,尚未持久的bank_accout(由于iban为空,因此将其忽略)。

如何为强参数使用这些?

我尝试了以下无济于事:

permitted_params = {
  :first_name,
  :last_name,
  { 
    :bank_accounts_attributes=>[:iban, :bic]
  }
}

params.require(:user).permit(*permitted_params)
Unpermitted parameters: -1, new-bank-account
# => {
       "user"=>{
         "first_name"=>"John",
         "last_name"=>"Doe",
         "bank_accounts_attributes"=>{}
       }
     }

我在这里做错了什么?

更新:

以下工作有效,但我不想在所有地方都明确包含否定键(代表非持久关系):

params.require(:user).permit(:first_name, :last_name,  bank_accounts_attributes: {"-1" => [:iban, :bic]})

更新2:

问题似乎出在“新银行帐户”键上:

p = ActionController::Parameters.new user: { first_name: "Foo", bank_accounts_attributes: {"-1" => {iban: 'xxx'}, "-2" => {iban: 'yyy'}}}
p.require(:user).permit(:first_name, bank_accounts_attributes: :iban)
# => {"first_name"=>"Foo", "bank_accounts_attributes"=>{"-1"=>{"iban"=>"xxx"}, "-2"=>{"iban"=>"yyy"}}}

p = ActionController::Parameters.new user: { first_name: "Foo", bank_accounts_attributes: {"-1" => {iban: 'xxx'}, "new-bank-account" => {iban: 'yyy'}}}
p.require(:user).permit(:first_name, bank_accounts_attributes: :iban)
# => {"first_name"=>"Foo", "bank_accounts_attributes"=>{}}

似乎我必须在提交表单之前从DOM中删除模板“ new-bank-account”。

我会回答我自己的问题:

强参数仅当它们为整数时才接受has_many键。 一个非整数键足以使所有嵌套记录从params哈希中消失。 因此,有两种解决方案:

  • 使用非整数密钥(例如“ new-entry”)作为模板,并在提交表单之前将其从DOM中删除。
  • 如果您像我一样,并且不想使用此多余的JS代码,请为模板使用保留的数字键,例如“ 999999”,并确保新的,持久的嵌套记录不会冲突。 由于持久记录的键是“ 0”,“ 1”等,因此我们使用一个分配“ -1”并递减计数的计数器。 另一种方法是使用时间戳,例如Date.now() (快速,但不适用于<= IE8)或+new Date() (速度较慢,但​​适用于IE8)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM