RubyRedGrapefruit
RubyRedGrapefruit

Reputation: 12214

How can I write a Ruby one-liner to read a small AR table into a hash?

I have a model called Category that contains about a thousand records. It changes extremely infrequently. I want to avoid millions of database hits by caching it, which is no big deal.

But I found that I didn't know how to do it in one line. I can do it in two:

category_hash = {}
Category.each { |c| category_hash[c.id] => category }

I know how to return a 2D array from the block. But is there a way to create and return a hash from such a block?

Upvotes: 1

Views: 103

Answers (3)

Stefan
Stefan

Reputation: 114158

In Rails there's Enumerable#index_by:

category_hash = Category.all.index_by(&:id)

Without Rails I'd use:

Hash[Category.all.map{ |c| [c.id, c] }]

Hash::[] creates a Hash from both, flat and nested Arrays:

Hash["a", 100, "b", 200]             #=> {"a"=>100, "b"=>200}
Hash[ [ ["a", 100], ["b", 200] ] ]   #=> {"a"=>100, "b"=>200}

Upvotes: 4

toro2k
toro2k

Reputation: 19228

Category.all.reduce(Hash.new) { |h, c| h[c.id] = c; h }

Upvotes: 3

Arup Rakshit
Arup Rakshit

Reputation: 118261

You can do this way:

Category.each_with_object({}) { |c,category_hash| category_hash[c.id] = category }

Upvotes: 2

Related Questions