Reputation: 2703
I have a form that I'm creating with an ENORMOUS list of questions. Rather than hard-code all these out in html.
I'm planning on storing them in a table called questions
and populating a questionnaire view by looping through the table with a script that pulls both the text of the question from one column, and its corresponding parameter from another.
The answers will be stored in a Questionnaire
model and table. This seems relatively straight-forward, except when dealing with strong params.
So I have the model Question
, and table questions
. Which contains the columns the_questions
and the_parameters
.
The questions contained in that table correspond to fields for the model Questionnaire
. 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.
So rather than:
def questionnaire_params
params.require(:questionnaire).permit(:an, :enormous, :list, :of, :params.....)
end
I'd like to do something like:
def questionnaire_params
@my_params=Questions.the_parameters
params.require(:questionnaire).permit(@my_params)
end
Is there any way to do this? Am I way out in left field with this idea? Any guidance or admonishment would be appreciated.
Upvotes: 1
Views: 440
Reputation: 477
ActionController::Parameters
takes an array:
$ 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}
Therefore, you can just pass your @my_params
as an array into permit
.
Upvotes: 0
Reputation: 102388
You don't need an enormous list of different parameters to do something as simple as a questionnaire. You're just doing it wrong. And you don't want to stuff a params whitelist in the DB. It would be slow and cause some real headaches when it comes to software versioning.
A fairly standard design for a questionnaire would be something like this:
<%= 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 %>
The params:
params.require(:questions).allow(question: [:answer_ids])
Upvotes: 0
Reputation: 2927
You may want to reconsider how you are modelling you application. Usually when you need to manipulate strong params, it is an indication of a code smell.
How are questions and answers and questionnaires related? As an alternative, consider this modelling:
You can get to the question through the answer. Your strong params for questionnaire would then be
params.require(:questionnaire).permit(
answers_attributes: [:id, :question_id, :text]
)
Upvotes: 2
Reputation: 52377
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.
This would mean, you'll permit all and each attribute to be massassigned.
To do so you just need to use permit!
method, which will whitelist every model's attribute:
params.require(:questionnaire).permit! # I don't want to even start discussing downsides of whitelisting all attributes
If you though have some attributes, you don't want to allow to be mass assigned and still want to use array, you can define
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
Upvotes: 3
Reputation: 3803
params.require(:questionnaire).permit(Questionaire.column_names.map(&:to_sym))
Check if this works for you.
Upvotes: 1
Reputation: 1889
I tried something like (Not sure if i got your question right though)
params.require(:parent).permit(ModelName.column_names)
But then you are defeating the purpose of strong params.
Try
params.require(:parent).permit(Parent.column_names - blacklist_array )
as in
params.require(:parent).permit(Parent.column_names - [:tax_num , :age])
Upvotes: 1