Make Array#collect return a hash
The Array#collect method is great for taking a hash or an array of objects and returning a new array based on the block you provide it, but sometimes you'd like to return a hash instead of an array. My primary use case for this is in testing Rails form posts with checkboxes. For instance, here is some HTML source of an imaginary page:
Car
Laptop
Television
When submitted to Rails with "Car" and "Television" checked, the above form should come over like this:
Processing PeopleController#update_item_status
(for 127.0.0.1 at 2007-02-11 17:00:41) [POST]
Session ID: asdf
Parameters: {"controller"=>"people", "action"=>"update_item_status",
"id"=>"1", "items" => {"1" => "1", "7" => "1"}}
When testing, you might want to build the items hash based on any number of items you specify. Using Array#collect, you'll get back an array, which won't work when building the params hash. What you need is something like the following:
# Usage: items.build_hash { |item| [ item.id, 1 ] } => { 1 => 1, 7 => 1, … }
returning(result = {}) do
self.each do |pair|
key, value = yield(pair)
result[key] = value
end
end
end
end
It's probably worth noting that the returning method is something included in Rails, so if you're not using this method inside a Rails project, you can either change the code to declare result = {} and then return result at the end of the method, or add the following code somewhere in your project:
yield(value)
value
end
end
January 26th, 2008 at 10:32 pm
Thank you. This worked splendidly for me. I was reimplementing some settings that I had as a hash in the session, moving it to the database. Now with your build_hash method, I can directly build an equivalent hash from the database. Much appreciated.