permitted_attributes 的强参数(在 Solidus 中)
Strong params with permitted_attributes (in Solidus)
我在 Rails 上为 Ruby 使用 Solidus 电子商务 gem。我正在创建一个用于发送邮件的电子商务网站,因此我需要能够将地址附加到各个行项目,而不仅仅是用户的账单地址和送货地址。为了实现这一点,我在购物车表单中传递地址参数。
我得到 Unpermitted parameter: address_attributes
。以下是我通过表单传递的参数:
参数
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[AUTHENTICITY_TOKEN]", "content"=>"",
"order"=>{"address_attributes"=>[{"firstname"=>"", "lastname"=>"", "address1"=>"", "address2"=>"", "city"=>"", "country_id"=>"232", "state_id"=>"", "zipcode"=>"", "phone"=>""}]}, "variant_id"=>"1", "quantity"=>"1", "button"=>""}
这是我访问它们的方式:address_attributes = order_params[:address_attributes]
。
这是Solidus自带的order_params方法:
orders_controller.rb
def order_params
if params[:order]
params[:order].permit(*permitted_order_attributes)
else
{}
end
end
(我不确定为什么它使用这个 if else 逻辑而不是 params.require,但这不是我的代码。)当我把调试器放在那里时,看看 permitted_order_attributes
这个是我看到的:
[:coupon_code, :email, :special_instructions, :use_billing, {:bill_address_attributes=>[:id, :firstname, :lastname, :first_name, :last_name, :address1, :address2, :city, :country_id, :state_id, :zipcode, :phone, :state_name, :country_iso, :alternative_phone, :company, {:country=>[:iso, :name, :iso3, :iso_name], :state=>[:name, :abbr]}], :ship_address_attributes=>[:id, :firstname, :lastname, :first_name, :last_name, :address1, :address2, :city, :country_id, :state_id, :zipcode, :phone, :state_name, :country_iso, :alternative_phone, :company, {:country=>[:iso, :name, :iso3, :iso_name], :state=>[:name, :abbr]}], :payments_attributes=>[:amount, :payment_method_id, :payment_method, {:source_attributes=>[:number, :month, :year, :expiry, :verification_value, :first_name, :last_name, :cc_type, :gateway_customer_profile_id, :gateway_payment_profile_id, :last_digits, :name, :encrypted_data, :existing_card_id,
{
:address_attributes=>[
:id, :firstname, :lastname, :first_name, :last_name, :address1, :address2, :city, :country_id, :state_id, :zipcode, :phone, :state_name, :country_iso, :alternative_phone, :company, {:country=>[:iso, :name, :iso3, :iso_name], :state=>[:name, :abbr]}
]
}
]}], :shipments_attributes=>[:special_instructions, :stock_location_id, :id, :tracking, :selected_shipping_rate_id]}, {:line_items_attributes=>[:id, :variant_id, :quantity]}]
于是,就有了address_attributes。奇怪的是它们被包裹在 {}
中。我的理解是,这意味着它正在寻找如下所示的参数:"order"=>{["address_attributes"=>{"firstname"=>"
...等。但我并不乐观。我不确定为什么 Solidus 正在寻找以这种方式传递的参数,而且我不确定如何编写我的表单以便它传递这样的参数。这是我的表格:
_cart_form.html.erb
<%= f.fields_for('address_attributes[][]', @address) do |form| %>
<%= render :partial => 'spree/address/form', :locals => { form: form,
address_type: 'shipping', address: @address } %>
<% end %>
变通
如果我将订单参数方法更改为:
def order_params
params.require(:order).permit(:address_attributes=>[:id, :firstname, :lastname, :first_name, :last_name, :address1, :address2, :city, :country_id, :state_id, :zipcode, :phone, :state_name, :country_iso, :alternative_phone, :company, {:country=>[:iso, :name, :iso3, :iso_name], :state=>[:name, :abbr]}])
end
那么我的表格就可以了。所以,我有一个解决方法,但我想了解这里发生了什么。有几种方法可以解决这个问题:
- 以符合现有
order_params
期望的形式传递参数。
- 修改 permitted_order_attributes 以接受我传入的参数。
我将你为 permitted_order_attributes
获得的内容转储到我喜欢使用的 JSON 格式化工具中,然后执行此操作:
[
: coupon_code,
: email,
: special_instructions,
: use_billing,
{
: bill_address_attributes=>[
: id,
: firstname,
: lastname,
: first_name,
: last_name,
: address1,
: address2,
: city,
: country_id,
: state_id,
: zipcode,
: phone,
: state_name,
: country_iso,
: alternative_phone,
: company,
{
: country=>[
: iso,
: name,
: iso3,
: iso_name
],
: state=>[
: name,
: abbr
]
}
],
: ship_address_attributes=>[
: id,
: firstname,
: lastname,
: first_name,
: last_name,
: address1,
: address2,
: city,
: country_id,
: state_id,
: zipcode,
: phone,
: state_name,
: country_iso,
: alternative_phone,
: company,
{
: country=>[
: iso,
: name,
: iso3,
: iso_name
],
: state=>[
: name,
: abbr
]
}
],
: payments_attributes=>[
: amount,
: payment_method_id,
: payment_method,
{
: source_attributes=>[
: number,
: month,
: year,
: expiry,
: verification_value,
: first_name,
: last_name,
: cc_type,
: gateway_customer_profile_id,
: gateway_payment_profile_id,
: last_digits,
: name,
: encrypted_data,
: existing_card_id,
{
: address_attributes=>[
: id,
: firstname,
: lastname,
: first_name,
: last_name,
: address1,
: address2,
: city,
: country_id,
: state_id,
: zipcode,
: phone,
: state_name,
: country_iso,
: alternative_phone,
: company,
{
: country=>[
: iso,
: name,
: iso3,
: iso_name
],
: state=>[
: name,
: abbr
]
}
]
}
]
}
],
: shipments_attributes=>[
: special_instructions,
: stock_location_id,
: id,
: tracking,
: selected_shipping_rate_id
]
},
{
: line_items_attributes=>[
: id,
: variant_id,
: quantity
]
}
]
在我看来,好像唯一出现的 address_attributes
嵌套在 payment_attributes
> source_attributes
中。这听起来像是您想要的结构不知何故被破坏了。
您最好忽略他们为您的受保护参数建议的代码,并以正常方式显式构建您想要的内容:
def order_params
params.require(:order).permit(:your, :choice, :of, :fields,
address_attributes: [:address, :fields],
other_nested_thing_attributes: [:stuff, :here])
end
您可以 100% 控制要从表单中接受的内容。这也将帮助您突出显示表单结构中的错误。
HTH - 评论或问题,大声说出来。
我在 Rails 上为 Ruby 使用 Solidus 电子商务 gem。我正在创建一个用于发送邮件的电子商务网站,因此我需要能够将地址附加到各个行项目,而不仅仅是用户的账单地址和送货地址。为了实现这一点,我在购物车表单中传递地址参数。
我得到 Unpermitted parameter: address_attributes
。以下是我通过表单传递的参数:
参数
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[AUTHENTICITY_TOKEN]", "content"=>"",
"order"=>{"address_attributes"=>[{"firstname"=>"", "lastname"=>"", "address1"=>"", "address2"=>"", "city"=>"", "country_id"=>"232", "state_id"=>"", "zipcode"=>"", "phone"=>""}]}, "variant_id"=>"1", "quantity"=>"1", "button"=>""}
这是我访问它们的方式:address_attributes = order_params[:address_attributes]
。
这是Solidus自带的order_params方法:
orders_controller.rb
def order_params
if params[:order]
params[:order].permit(*permitted_order_attributes)
else
{}
end
end
(我不确定为什么它使用这个 if else 逻辑而不是 params.require,但这不是我的代码。)当我把调试器放在那里时,看看 permitted_order_attributes
这个是我看到的:
[:coupon_code, :email, :special_instructions, :use_billing, {:bill_address_attributes=>[:id, :firstname, :lastname, :first_name, :last_name, :address1, :address2, :city, :country_id, :state_id, :zipcode, :phone, :state_name, :country_iso, :alternative_phone, :company, {:country=>[:iso, :name, :iso3, :iso_name], :state=>[:name, :abbr]}], :ship_address_attributes=>[:id, :firstname, :lastname, :first_name, :last_name, :address1, :address2, :city, :country_id, :state_id, :zipcode, :phone, :state_name, :country_iso, :alternative_phone, :company, {:country=>[:iso, :name, :iso3, :iso_name], :state=>[:name, :abbr]}], :payments_attributes=>[:amount, :payment_method_id, :payment_method, {:source_attributes=>[:number, :month, :year, :expiry, :verification_value, :first_name, :last_name, :cc_type, :gateway_customer_profile_id, :gateway_payment_profile_id, :last_digits, :name, :encrypted_data, :existing_card_id,
{
:address_attributes=>[
:id, :firstname, :lastname, :first_name, :last_name, :address1, :address2, :city, :country_id, :state_id, :zipcode, :phone, :state_name, :country_iso, :alternative_phone, :company, {:country=>[:iso, :name, :iso3, :iso_name], :state=>[:name, :abbr]}
]
}
]}], :shipments_attributes=>[:special_instructions, :stock_location_id, :id, :tracking, :selected_shipping_rate_id]}, {:line_items_attributes=>[:id, :variant_id, :quantity]}]
于是,就有了address_attributes。奇怪的是它们被包裹在 {}
中。我的理解是,这意味着它正在寻找如下所示的参数:"order"=>{["address_attributes"=>{"firstname"=>"
...等。但我并不乐观。我不确定为什么 Solidus 正在寻找以这种方式传递的参数,而且我不确定如何编写我的表单以便它传递这样的参数。这是我的表格:
_cart_form.html.erb
<%= f.fields_for('address_attributes[][]', @address) do |form| %>
<%= render :partial => 'spree/address/form', :locals => { form: form,
address_type: 'shipping', address: @address } %>
<% end %>
变通
如果我将订单参数方法更改为:
def order_params
params.require(:order).permit(:address_attributes=>[:id, :firstname, :lastname, :first_name, :last_name, :address1, :address2, :city, :country_id, :state_id, :zipcode, :phone, :state_name, :country_iso, :alternative_phone, :company, {:country=>[:iso, :name, :iso3, :iso_name], :state=>[:name, :abbr]}])
end
那么我的表格就可以了。所以,我有一个解决方法,但我想了解这里发生了什么。有几种方法可以解决这个问题:
- 以符合现有
order_params
期望的形式传递参数。 - 修改 permitted_order_attributes 以接受我传入的参数。
我将你为 permitted_order_attributes
获得的内容转储到我喜欢使用的 JSON 格式化工具中,然后执行此操作:
[
: coupon_code,
: email,
: special_instructions,
: use_billing,
{
: bill_address_attributes=>[
: id,
: firstname,
: lastname,
: first_name,
: last_name,
: address1,
: address2,
: city,
: country_id,
: state_id,
: zipcode,
: phone,
: state_name,
: country_iso,
: alternative_phone,
: company,
{
: country=>[
: iso,
: name,
: iso3,
: iso_name
],
: state=>[
: name,
: abbr
]
}
],
: ship_address_attributes=>[
: id,
: firstname,
: lastname,
: first_name,
: last_name,
: address1,
: address2,
: city,
: country_id,
: state_id,
: zipcode,
: phone,
: state_name,
: country_iso,
: alternative_phone,
: company,
{
: country=>[
: iso,
: name,
: iso3,
: iso_name
],
: state=>[
: name,
: abbr
]
}
],
: payments_attributes=>[
: amount,
: payment_method_id,
: payment_method,
{
: source_attributes=>[
: number,
: month,
: year,
: expiry,
: verification_value,
: first_name,
: last_name,
: cc_type,
: gateway_customer_profile_id,
: gateway_payment_profile_id,
: last_digits,
: name,
: encrypted_data,
: existing_card_id,
{
: address_attributes=>[
: id,
: firstname,
: lastname,
: first_name,
: last_name,
: address1,
: address2,
: city,
: country_id,
: state_id,
: zipcode,
: phone,
: state_name,
: country_iso,
: alternative_phone,
: company,
{
: country=>[
: iso,
: name,
: iso3,
: iso_name
],
: state=>[
: name,
: abbr
]
}
]
}
]
}
],
: shipments_attributes=>[
: special_instructions,
: stock_location_id,
: id,
: tracking,
: selected_shipping_rate_id
]
},
{
: line_items_attributes=>[
: id,
: variant_id,
: quantity
]
}
]
在我看来,好像唯一出现的 address_attributes
嵌套在 payment_attributes
> source_attributes
中。这听起来像是您想要的结构不知何故被破坏了。
您最好忽略他们为您的受保护参数建议的代码,并以正常方式显式构建您想要的内容:
def order_params
params.require(:order).permit(:your, :choice, :of, :fields,
address_attributes: [:address, :fields],
other_nested_thing_attributes: [:stuff, :here])
end
您可以 100% 控制要从表单中接受的内容。这也将帮助您突出显示表单结构中的错误。
HTH - 评论或问题,大声说出来。