Rails强参数:如何接受模型和非模型属性?

时间:2014-11-02 20:04:38

标签: ruby-on-rails strong-parameters

我有一个表单来创建一个具有所有常用属性的用户模型,但我也传递了很多非模型属性,基于此我将在我的控制器操作中创建更多内容。

我的问题是如何告诉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,但是我在这种形式中有越来越多的属性列表与用户模型本身无关(但对于创建用户模型和随后的相关模型)。我们可以辩论这不是最好的方法(想到一个表格对象),但目前我想看看强参数是否可以帮助我。

2 个答案:

答案 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