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 usingSo you could try topermit!
as it will allow all
current and future model attributes to be mass-assigned.
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:
In my app, the category_ids are passed to the create action in an arrayThe 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 => [])
"category_ids"=>["", "2"],
Therefore, when declaring strong parameters, I explicitly set category_ids to be an arrayparams.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
Rails: Before Process_Action Callback: Authenticate_User! Has Not Been Defined
Error Could Not Find I18N-0.7.0 in Any of The Sources
Fixing The "Ruby Installation Is Missing Psych" Error
Sorting Hash of Hashes by Value (And Return The Hash, Not an Array)
Include Module in All Minitest Tests Like in Rspec
Error Installing Rdoc Documentation: Incompatible Encoding Regexp Match
How to Add a User Interrupt to an Infinite Loop
What Is - Gets Is a Directory - Error Message
Adding Bootstrap Icon to Button in Ruby on Rails
Converting Ruby Hashes to Arrays
How to Reference a Local Gem from a Ruby Script
Dynamic Role Attributes in Chef
Ruby Dynamic Arguments in Dynamically Created Methods
Rake Aborted: Could Not Find Rspec
Ruby - Append Content at The End of The Existing S3 File Using Fog