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

n_x*_*x_l 4 ruby-on-rails strong-parameters

我有一个使用所有常用属性创建用户模型的表单,但是我还传递了许多非模型属性,基于这些属性,我将在控制器操作中创建更多内容。

我的问题是如何告诉“强参数”接受用户数据以及与用户数据库无关的其他数据?

为了说明这一点,我的表单可能是这样的(为简洁起见删除了提交按钮):

<%= 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 %>
Run Code Online (Sandbox Code Playgroud)

如何使用强参数来执行此操作?我尝试了这个:

params.require(:user).permit(:attribute1, :attribute2 , :attribute3, :attribute_not_on_user_model1, 
  attribute_not_on_user_model2)
Run Code Online (Sandbox Code Playgroud)

还有这个:

params.require(:user).permit(:attribute1, :attribute2 ,     
  :attribute3).require(:attribute_not_on_user_model1, 
  attribute_not_on_user_model2)
Run Code Online (Sandbox Code Playgroud)

两者都不起作用。我知道可以attr_accessor在用户中使用,但是这种形式的属性列表越来越多,这些属性本身与用户模型无关(但是对于创建用户模型及其后续相关模型而言必不可少) 。我们可能会争论这不是执行此操作的最佳方法(会想到一个表单对象),但目前我想看看Strong Parameters是否可以在这里帮助我。

Sim*_*tti 5

user模型属性存储在:user哈希中,而非用户属性可直接在参数级别访问。

如果检查params哈希,您会注意到它是通过以下方式构造的

{ user: { attribute1: "value", attribute2: value, ... }, attribute_not_on_user_model1: "value", attribute_not_on_user_model2: "value" }
Run Code Online (Sandbox Code Playgroud)

因此,电话

params.require(:user)
Run Code Online (Sandbox Code Playgroud)

将自动忽略不属于该user节点的任何其他参数。如果您还想包含其他参数,则可以编写哈希,或更新视图以将参数注入表单。

在表单上注入参数会使参数成为同一: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 %>
Run Code Online (Sandbox Code Playgroud)

另一个解决方案是

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
Run Code Online (Sandbox Code Playgroud)

但是,解决方案实际上取决于您以后如何使用这些参数。如果所有这些参数都作为单个哈希发送,则您可能希望组成单个哈希,但在这种情况下,您可能还需要虚拟属性。

关键是,如果没有真正的用例,问题本身就毫无意义。StrongParameters旨在过滤传递给批量创建或批量更新操作的一组参数。通常,这意味着您有一个模型。

如果您设计的是自定义方法,或者您具有非模型方法,那么只要您可以控制正在编写和调用的方法,就可以将StrongParameters白名单列入清单。