views:

43

answers:

2

I've got a form that allows the user to put together a hash.

The hashes desired end format would be something like this:
{1 => "a", 2 => "x", 3 => "m"}

I can build up something similar by having lots of inputs that have internal brackets in their names:

<%= hidden_field_tag "article[1]", :value => a %>

However, the end result is that builds a hash where all the keys are strings and not integers:
{"1" => "a", "2" => "x", "3" => "m"}

I'm currently fixing this by generating a new hash in the controller by looping over the input hash, and then assigning that to params. Is there a cleaner, DRYer way to do this?

+1  A: 

Your params will always come in with string keys and values. The easiest way to fix this is to either write your own extension to Hash or simply inject as required:

numeric_keys = params['article'].inject({ }) do |h, (k, v)|
  h[k.to_i] = v
  h
end

Then you have a hash with the keys converted to integer values, as you like.

A simple extension might be:

class Hash
  def remap_keys
    inject({ }) do |h, (k, v)|
      h[yield(k)] = v
      h
    end
  end
end

This is much more generic and can be used along the lines of:

params['article'].remap_keys(&:to_i)
tadman
+1  A: 

That depends a bit what you want to use it for. Maybe it is easier to just use strings as keys, and do the "conversion" when accessing the array (or not at all)?

It is also possible to build an array using something like

<%= hidden_field_tag "article[]", :value => "x" %>

this will return "article" as an array, and you can access it directly by index. However, there is no way to influence the position - the array will contain all values in order of appearance.

Lastly, you can make your own version of Hash or just modify the keys, as has been explained.

averell