syntatic

ruby on rails: merge! ‘params’ with a hash indifferently

with 3 comments

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.

About these ads

Written by syntatic

November 28, 2007 at 10:01 pm

Posted in programming, rails

3 Responses

Subscribe to comments with RSS.

  1. 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

  2. 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

  3. […] ту же тему: ruby on rails: merge! ‘params’ with a hash indifferently. Запись опубликована в рубрике Программирование с […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: