我有一个表单来创建具有所有常用属性的用户模型,但我还传递了许多非模型属性,基于这些属性我将在我的 Controller 操作中创建更多内容。
我的问题是如何告诉强参数接受用户数据以及与用户数据库无关的其他数据?
为了说明,我的表单可能是这样的(为简洁起见,删除了提交按钮):
<%= 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
在用户中,但我有越来越多的这种形式的属性,这些属性与用户模型本身无关(但对于用户模型及其后续相关模型的创建仍然是必不可少的)。我们可以争论这不是最好的方法(想到一个表单对象),但目前我想看看强参数是否可以帮助我。
最佳答案
user
模型属性存储在 :user
中哈希,而非用户属性可以直接在参数级别访问。
如果您检查您的 params
Hash,你会注意到它是通过以下方式构造的
{ user: { attribute1: "value", attribute2: value, ... }, attribute_not_on_user_model1: "value", attribute_not_on_user_model2: "value" }
因此,调用
params.require(:user)
将自动忽略不属于
user
的任何其他参数节点。如果您还想包含其他参数,您可以组合散列,或更新 View 以在表单中注入(inject)参数。在表单上注入(inject)参数将导致参数成为同一
: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 白名单可能没有任何意义,因为您可以控制正在编写和调用的方法。
关于ruby-on-rails - Rails 强参数 : How to accept both model and non-model attributes?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26703770/