How to Use Strong Parameters with an Objects Array in Rails

How to use strong parameters with an objects array in Rails

To accept an array of objects, put the params in an array:

params.permit(
users_to_employers: [
:start_date,
:end_date,
employer: [ :company_name ]
]
)

Strong parameters in rails with array as root object

Ideally you should always send a JSON objects as a param, when you don't explicitly give a key for object, it takes _json as is the case with your params.

Anyway to write a strong parameter in your case, you can do something like,

params = ActionController::Parameters.new({
"_json" => [
{"id"=>1, "fruit_ids"=>[1, 2, 3]},
{"id"=>2, "fruit_ids"=>[4, 5, 6]}
],
"format"=>"json",
"controller"=>"...",
"action"=>"..."
}

params.permit('_json': [:id, fruit_ids: []]) # You need this line.

# => {"_json"=>[{"id"=>1, "fruit_ids"=>[1, 2, 3]}, {"id"=>2, "fruit_ids"=>[4, 5, 6]}]}

Rails Strong Params how to Permit a nested Array

As Ruby on Rails API states, when using ActionController::Parameters you want to declare that a parameter should be an array (list) by mapping it to a empty array. Like you did with release_times.

You should permit targeting params with [days: [], gender: []] instead of [:days, :gender]. This should solve the error.

But even them, release_times is an array of arrays, which I believe is not supported at the moment (there is an old issue for it).

One way you could bypass this would be by changing the way you're communicating release_times. Using an arrays of hashes instead of nested arrays.

From this:

"release_times"=>[["4:00", "5:00"], ["5:00", "6:00"]]

To this (or something similar):

"release_times"=>[{"start" => "4:00", "end"=>"5:00"}, {"start" =>"5:00", "end" => "6:00"}]

That way, you could do this:

safe_params = params.require(:data).permit(attributes: [:id, :created_at, :title, { targeting: [days: [], gender: [], release_times: [:start, :end]] }])

Exactly how you would implement that is up to you, but I hope it helps.

**Also, there was a typo with release_times.


You can do some testing yourself. Open rails c and do something like this:

param = ActionController::Parameters.new("targeting"=> { "release_times"=>[["4:00", "5:00"], ["5:00", "6:00"]]})
param.require(:targeting).permit(release_times: []) # > Doesn't return times.

new_param = ActionController::Parameters.new("targeting"=> { "release_times"=>[{"start" => "4:00", "end"=>"5:00"}, {"start" =>"5:00", "end" => "6:00"}] })
new_param.require(:targeting).permit(release_times: [:start, :end]) # > Return times.

Just an observation, using permit! would work. But as strong params doc says:

Extreme care should be taken when using permit! as it will allow all
current and future model attributes to be mass-assigned.

So you could try to slice arguments yourself and them permit! - but I can't tell you that's the way to go.

Learn more about Mass Assignment Vulnerability here.

nested array in strong parameters

Try it this way, it should work:

params.require(:project).permit(
:title,
:description,
config: {
service: [
:domains,
web: [:auth, :user, :pass]
]
},
documents: []
)

how to permit an array with strong parameters

This https://github.com/rails/strong_parameters seems like the relevant section of the docs:

The permitted scalar types are String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO,
ActionDispatch::Http::UploadedFile and Rack::Test::UploadedFile.

To declare that the value in params must be an array of permitted scalar values map the key to an empty array:

params.permit(:id => [])

In my app, the category_ids are passed to the create action in an array

"category_ids"=>["", "2"],

Therefore, when declaring strong parameters, I explicitly set category_ids to be an array

params.require(:question).permit(:question_details, :question_content, :user_id, :accepted_answer_id, :province_id, :city, :category_ids => [])

Works perfectly now!

(IMPORTANT: As @Lenart notes in the comments, the array declarations must be at the end of the attributes list, otherwise you'll get a syntax error.)

Rails Strong Parameters - Allow parameter to be an Array or String

You could check if params[:strings] is an array and work from there

def strong_params
if params[:string].is_a? Array
params.fetch(:search, {}).permit(strings: [])
else
params.fetch(:search, {}).permit(:strings)
end
end


Related Topics



Leave a reply



Submit