Skip to content
This repository has been archived by the owner on Aug 17, 2017. It is now read-only.

Permit ActionController::AnyParam on hashes #193

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

alvarezloaiciga
Copy link

A way to support any args within a hash, for Rails APIs this is very useful

@rafaelfranca
Copy link
Member

What is the difference between this and permit!?

@alvarezloaiciga
Copy link
Author

It works within the permit, so for example home.permit(owner: [ :name, :age, children: ActionController::AnyParam ] ). So it's to scope the permit all.

@rafaelfranca
Copy link
Member

I mean, we already have permit! to permit all the values in a scope. Is there any difference?

@alvarezloaiciga
Copy link
Author

how can you do this (owner: [ :name, :age, child: ActionController::AnyParam ] ) it will return { owner: { name: "Owner name", age: 31, child: { name: "name", whatever: "whatever" } } with a permit!. I though permit! only works for the entire hash. As it is in the test https://github.com/rails/strong_parameters/pull/193/files#diff-cc5c50ab9fdafbbeab836323faf59132R367

@rafaelfranca
Copy link
Member

>> permited = params.permit(owner: [:name, :age])
=> {"owner"=>{"name"=>"Owner name", "age"=>31}}
>> permited[:owner][:child] = params[:owner][:child].permit!
=> {"name"=>"name", "whatever"=>"whatever"}
>> permited
=> {"owner"=>{"name"=>"Owner name", "age"=>31, "child"=>{"name"=>"name", "whatever"=>"whatever"}}}

@alvarezloaiciga
Copy link
Author

yep, but imagine you have an array of chidren and on each of them there is a girlfriend Hash that you want to permit it all, so then you will need a method to iterate over the array and do what you are doing there

permitted = params.permit(owner: [ children: [ :name, :age ] ] )
params[:owner][:children].each_with_index do |child, index|
   permited[:owner][:children][index][:girlfriend] = child[:girlfriend]
end

An also doing the permit on the children attributes you want there.

rather than just doing

params.permit(owner: [ children: [ :name, :age, girlfriend: ActionController::AnyParam ] ]

And if there is an array within that girlfriend's array it's going to be a mess, because the complexity on doing it will grow exponentially

@rafaelfranca
Copy link
Member

I'm almost sure it is possible to do with permit! but I'm not going to try.

This repository is only to Rails < 4 support, so if you want this you should submit your pull request to rails/rails.

@Fire-Dragon-DoL
Copy link

@rafaelfranca I found a usecase where permit! won't work: when you have an array of hashes with one of the field being a hash of unknown keys (which should all be allowed). Now this looks like a security flaw but it is not if you consider that this dynamic hash it's an hstore field, so it will become a common use case: submit multiple rows at once with one hstore field each.

You can do it with plain ruby obviously, but I think the purpose of strong_parameters it's also making these things easier.

Here's my example:

{ contact_sources: [
  { id: 1, filled_fields: { randomstuff: 'randomdata', dunno: 123 } },
  { id: 2, filled_fields: { blah: 'blabla', dunno: 9043 } }
] }

And what I tried:

params.permit(contact_sources: [{:filled_fields => []}, 'id'])

Something like this should be enough (it's a very simple idea):

params.permit(contact_sources: [{:filled_fields => true}, 'id'])

A reference to my original StackOverflow question: http://stackoverflow.com/questions/24794040/allow-an-array-of-hashes-with-a-dynamic-hash-hstore-inside

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants