Skip to content

Nested hashes derail Rails’ url_for helpers

While working on the Sicirec PostgreSQL database front-end today, I had to pass a lot of nested parameters to a link_to helper in Rails. Software being what it is, this didn’t work.

There are a few patches awaiting acceptance. The most promising of these patches was part of an open Trac ticket. Because we use Rails as an svn external, applying the patch myself wouldn’t work when deploying unless I’d create a vendor branch for Rails in our own repository. Hoping that someone had forgotten to close the ticket, I first tried to upgrade to Rails 1.2.2, which was about time anyway because we were still in the 1.1 branch. The upgrade went fine but didn’t fix the problem.

Next, I tried to integrate the patch by redefining the methods changed by the patch in our lib/ directory. When this didn’t work, I decided to simply do some flattening of the hash myself for this one particular case.

A bit of googling around gave me many clues that the problem has cost a lot of people lots of time already.

Eventually, I settled with a derivate of some code by Peter Marklund to flatten my hashes:

class Hash
  # Flatten a hash into a flat form suitable for an URL.
  # Accepts as an optional parameter an array of names that pretend to be the ancestor key names.
  #
  # Example 1:
  #
  #   { 'animals' => {
  #       'fish' => { 'legs' => 0, 'sound' => 'Blub' }
  #       'cat' => { 'legs' => 4, 'sound' => 'Miaow' }
  #   }.flatten_for_url
  #
  #   # => { 'animals[fish][legs]'  => 0,
  #          'animals[fish][sound]' => 'Blub',
  #          'animals[cat][legs]'   => 4,
  #          'animals[cat][sound]'  => 'Miaow'
  #        }
  #
  # Example 2:
  #
  #   {'color' => 'blue'}.flatten_for_url( %w(world things) )  # => {'world[things][color]' => 'blue'}
  #
  def flatten_for_url(ancestor_names = [])
    flat_hash = Hash.new
 
    each do |key, value|
      names = Array.new(ancestor_names)
      names << key
 
      if value.is_a?(Hash)
        flat_hash.merge!(value.flatten_for_url(names))
      else
        flat_key = names.shift.to_s.dup
        names.each do |name|
          flat_key << "[#{name}]"
        end
        flat_key << "[]" if value.is_a?(Array)
        flat_hash[flat_key] = value
      end
    end
 
    flat_hash
  end
end

As you can see, I turned my code into a single method of the Hash class. It can be used simply in any url_for (based) call as in the following example:

url_for {
    :controller => 'post',
    :action => 'new',
    'author' => {'name' => 'Rowan', 'gender' => 'm'}
  }.flatten_for_url
  # => /post/new?author[name]=Rowan&author[gender]=m 

Now if only some Rails developer would commit the patch already.


    11 Comments ( Add comment / trackback )

    1. On May 25, 2016 at 05:28

      john lewis furniture outlet manchester

      BigSmoke » Nested hashes derail Rails’ url_for helpers

    2. On May 27, 2016 at 06:35

      Online indian stores in Usa

      BigSmoke » Nested hashes derail Rails’ url_for helpers

    3. On Jun 09, 2016 at 06:34

      click the up coming web page

      BigSmoke » Nested hashes derail Rails’ url_for helpers

    4. On Jul 12, 2016 at 05:11

      amazon online coupon codes electronics

      BigSmoke » Nested hashes derail Rails’ url_for helpers

    5. On Jul 19, 2016 at 05:41

      bharat heavy electricals limited bhopal

      BigSmoke » Nested hashes derail Rails’ url_for helpers

    6. (permalink) Trackback from www.chgg08.com
      On Jul 23, 2016 at 08:52

      http://www.chgg08.com

      BigSmoke » Nested hashes derail Rails’ url_for helpers

    7. (permalink) Trackback from sctszy.cn
      On Aug 02, 2016 at 13:44

      sctszy.cn

      BigSmoke » Nested hashes derail Rails’ url_for helpers

    8. On Aug 10, 2016 at 18:11

      ticketmaster voucher code august 2012

      BigSmoke » Nested hashes derail Rails’ url_for helpers

    9. On Sep 03, 2016 at 15:25

      hotels in cornwall uk 5 star

      BigSmoke » Nested hashes derail Rails’ url_for helpers

    10. On Sep 13, 2016 at 23:24

      electrician apprenticeships in ohio

      BigSmoke » Nested hashes derail Rails’ url_for helpers

    11. On Sep 27, 2016 at 03:21

      creating an online shop website

      BigSmoke » Nested hashes derail Rails’ url_for helpers