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.