我有一个表单来创建一个具有所有常用属性的用户模型,但我也传递了很多非模型属性,基于此我将在我的控制器操作中创建更多内容。
我的问题是如何告诉Strong Parameters接受用户数据,以及与用户db明智无关的其他数据?
为了说明,我的表单可能喜欢这样(提交按钮因为简洁而被删除):
<%= form_for @user do |f| %>
<%= f.text_field 'attribute1' %>
<%= f.text_field 'attribute2' %>
<%= f.text_field 'attribute3' %>
<%= text_field_tag 'attribute_not_on_user_model1' %>
<%= text_field_tag 'attribute_not_on_user_model2' %>
<% end %>
如何使用强参数执行此操作?我试过这个:
params.require(:user).permit(:attribute1, :attribute2 , :attribute3, :attribute_not_on_user_model1,
attribute_not_on_user_model2)
还有这个:
params.require(:user).permit(:attribute1, :attribute2 ,
:attribute3).require(:attribute_not_on_user_model1,
attribute_not_on_user_model2)
两者都不起作用。我知道我可以在用户中做attr_accessor
,但是我在这种形式中有越来越多的属性列表与用户模型本身无关(但对于创建用户模型和随后的相关模型)。我们可以辩论这不是最好的方法(想到一个表格对象),但目前我想看看强参数是否可以帮助我。
答案 0 :(得分:4)
user
模型属性存储在:user
哈希中,而非用户属性可直接在params级别访问。
如果您检查params
Hash,您会注意到它是按照以下方式构建的
{ user: { attribute1: "value", attribute2: value, ... }, attribute_not_on_user_model1: "value", attribute_not_on_user_model2: "value" }
因此,电话
params.require(:user)
将自动忽略不属于user
节点的任何其他参数。如果你想包括其他参数,你要么组成哈希,要么更新视图以在表格中注入参数。
在表单上注入参数将导致params成为同一:user
节点的一部分。这种方法通常适用于虚拟属性(尽管这些概念没有相互关联)。
<%= form_for @user do |f| %>
<%= f.text_field 'attribute1' %>
<%= f.text_field 'attribute2' %>
<%= f.text_field 'attribute3' %>
<%= text_field_tag 'user[attribute_not_on_user_model1]' %>
<%= text_field_tag 'user[attribute_not_on_user_model2]' %>
<% end %>
另一种解决方案就像是
def some_params
hash = {}
hash.merge! params.require(:user).slice(:attribute1, :attribute2, :attribute3)
hash.merge! params.slice(:attribute_not_on_user_model1,
attribute_not_on_user_model2)
hash
end
然而,解决方案实际上取决于您以后如何使用这些参数。如果所有这些参数都作为单个哈希发送,那么您可能想要组合单个哈希,但在这种情况下,您可能还需要虚拟属性。
关键在于,如果没有真正的用例,问题本身就是无意义的。 StrongParameters旨在过滤传递给批量创建或批量更新操作的一组参数。通常,这意味着您有一个模型。
如果你设计一个自定义方法,或者你有非模型方法,StrongParameters白名单可能没有任何意义,因为你可以控制你正在编写和调用的方法。
答案 1 :(得分:0)
有很多方法可以做到这一点,一种方法是使用accepts_nested_attributes_for:http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html