This was a gotcha for me. reverse_params! is generally used to set default values on a hash. In the case of the params hash, that is accessible in the controller from an http action, it uses stringed keys and not symbolic keys. The following wasn’t working correctly because my resulting hash had two page keys set; one as a stringed key and one as a symbolic key.
BROKEN SCENARIO: original params hash is the following: {‘page’=>‘2’} params.reverse_merge!( :page => 1, :sort_by => ‘new’, :view_by => ‘all’ ) result: {:page => 1, :sort_by => ‘new’, :view_by => ‘all’ , ‘page’=>‘2’}
CORRECT SCENARIO: original params hash is the following: {‘page’=>‘2’} params.reverse_merge!( ‘page’ => 1, ‘sort_by’ => ‘new’, ‘view_by’ => ‘all’ ) result: {‘page’ => 1, ‘sort_by’ => ‘new’, ‘view_by’ => ‘all’}
Trying to access the :page in the first scenario gives you a value of 1, set by the default values, where you really want 2, passed in to the controller.

June 13th, 2008 at 12:44 AM
That is because 'page' and :page aren't the same object. The only way a hash in Rails now (with Ruby 1.8) responds to a symbol or a string is by using a HashWithIndifferentAccess. The params hash is a HashWithIndifferentAccess, but you were merging with a normal hash. I believe this is why you encountered that result.
IIRC this has changed in Ruby 1.9. The hashes are going to respond to either a symbol or a string, leading to mass confusion :)
Best of luck! DrMark
July 22nd, 2008 at 11:01 PM
HashWithIndifferentAccess - Thanks for the tip DrMark!
'Sup Rodney!
--Duke
July 29th, 2008 at 01:45 AM
I've submitted a patch for this to rails core:
http://rails.lighthouseapp.com/projects/8994/tickets/421-hash-with-indifferent-access-reverse-merge-problem