使用数组定义强参数

Using an array to define strong params

我正在创建一个包含大量问题列表的表格。而不是将所有这些都硬编码在 html 中。

我计划将它们存储在一个名为 questions 的 table 中,并通过使用脚本循环遍历 table 来填充问卷视图,该脚本同时提取问题的文本来自一列,以及来自另一列的相应参数。

答案将存储在 Questionnaire 模型和 table 中。这看起来相对简单,除非在处理强参数时。

所以我有模型 Question 和 table questions。其中包含列 the_questionsthe_parameters

table 中包含的问题对应于模型 Questionnaire 的字段。我想查询数据库以获取参数数组,然后将它们放入问卷控制器中的强参数中。

所以而不是:

def questionnaire_params
  params.require(:questionnaire).permit(:an, :enormous, :list, :of, :params.....)
end

我想做这样的事情:

def questionnaire_params
  @my_params=Questions.the_parameters
  params.require(:questionnaire).permit(@my_params)
end

有什么办法吗?我有这个想法吗?任何指导或警告将不胜感激。

I would like to query the database to get an array of the parameters and then drop them into the strong params in the questionnaire controller.

这意味着,您将允许对所有属性和每个属性进行批量分配。

为此,您只需要使用 permit! 方法,该方法会将 每个 模型的属性列入白名单:

params.require(:questionnaire).permit! # I don't want to even start discussing downsides of whitelisting all attributes

如果你虽然有一些属性,但不想允许被批量赋值,但仍想使用数组,你可以定义

def questionnaire_params
  @all_attributes = Model.column_names.map(&:to_sym)
  @not_permitted = [:id, :some_other_attribute]
  params.require(:questionnaire).permit(@all_attributes - @not_permitted)
end

我试过类似的东西(但不确定我是否回答你的问题)

params.require(:parent).permit(ModelName.column_names)

但是这样你就违背了强参数的目的。

尝试

params.require(:parent).permit(Parent.column_names - blacklist_array )

params.require(:parent).permit(Parent.column_names - [:tax_num , :age])
params.require(:questionnaire).permit(Questionaire.column_names.map(&:to_sym))

检查这是否适合您。

ActionController::Parameters 接受一个数组:

$ bin/rails c
> params = ActionController::Parameters.new(user: {name: 'John', age: 22})
=> {"user"=>{"name"=>"John", "age"=>22}} 
> permitted = params.require(:user).permit(:name, :age)
=> {"name"=>"John", "age"=>22} 
> permitted = params.require(:user).permit([:name, :age])
=> {"name"=>"John", "age"=>22} 
> permitted = params.require(:user).permit(*[:name, :age])
=> {"name"=>"John", "age"=>22} 
> permitted = params.require(:user).permit('name', 'age')
=> {"name"=>"John", "age"=>22}

因此,您可以将 @my_params 作为数组传递给 permit

您可能需要重新考虑如何为应用程序建模。通常,当您需要操作强参数时,这表明存在代码异味。

问答和问卷有什么关系?作为替代方案,请考虑以下建模:

  • 一份问卷 has_many 个答案和 has_many 个问题
  • 一个答案belongs_to一个问题和belongs_to一个问卷
  • 一个问题has_many个答案

您可以通过答案进入问题。那么您的问卷强参数将是

params.require(:questionnaire).permit(
  answers_attributes: [:id, :question_id, :text]
)

您不需要大量的不同参数来完成像调查问卷这样简单的事情。你只是做错了。而且您不想在数据库中填充参数白名单。当涉及到软件版本控制时,它会很慢并且会引起一些真正的麻烦。

一个相当标准的问卷设计应该是这样的:

<%= form_for(:questions, controller: 'questions', action: 'create') do |form| %>
    <% @questions.each do |question| %> 
        <fieldset>
        <%= fields_for(question) do |qf| %>
          <legend><%= question.title %></legend>
          <%= qf.collection_check_boxes :answer_ids, question.answers, :id, :text %>
        <% end %>
        </fieldset>
    <% end %>
<% end %> 

参数:

params.require(:questions).allow(question: [:answer_ids])