ruby on rails: merge! ‘params’ with a hash indifferently
When using a merge! with the params method key value pairs are not clobbered if the calling hash is using symbols as keys.
If params[:colors] contains:
params[:colors] = { "blue" => false, "green" => true }
and sym_hsh contains:
sym_hsh = { :blue => true, :red => false }
a merge! of the two will result in this:
sym_hsh.merge!(params[:colors])
=> { "blue"=> false, :blue => true, :red => false, "green" => true }
Notice the duplicate blue key and mixed key types. Some are symbols and some are strings.
Using rails you probably haven’t run into this problem much. Behind the scenes in most of rails hashes are made indifferent to key type. Indifference protects developers from running into problems with strings and symbols as hash keys.
The rails code base uses the class HashWithIndifferentAccess allowing hashes to use strings and hashes interchangeably.
When creating new hashes in a rails project it is best to avoid the problem alongside rails. You can do this by creating hashes two different ways:
hsh = HashWithIndifferentAccess.new( :blue => true, :red => false)
or this which does the above for you:
{ :blue => true, :red => false }.with_indifferent_access
Now the merge! will clobber :blue instead of appending another :blue key.
That’s awesome! I’ve been looking for a solution to this problem for a while now. Thank you!
Moo
October 15, 2008 at 12:18 pm
Hi,
Good stuff – I hadn’t considered the indifferent access portion of this problem – thanks for bringing it up. I wrote a “deep merge” tool for hashes to facilitate merging more complex hash structures (as often are created by Rails params/form interaction). Might be of interest for you as well:
http://www.misuse.org/science/2008/05/19/deep_merge-ruby-recursive-merging-for-hashes/
I’ll stuff in the indifferent access portions at some point (though I’d guess if you create an indifferent access hash and mix-in deep merge, it will work that way right out of the box)
stevemidgley
May 1, 2009 at 11:08 am
[...] ту же тему: ruby on rails: merge! ‘params’ with a hash indifferently. Запись опубликована в рубрике Программирование с [...]
Ruby on Rails: HashWithIndifferentAccess
October 10, 2012 at 6:38 am