Michel Kenneth Hansen
Michel Kenneth Hansen

Reputation: 51

Rails: How to convert a query result hash

I am currently struggling with something which should be pretty straightforward in Rails.

I would like to issue one ActiveRecord query and fetch model objects from the database and subsequently store those in a hash for later lookup.

I have done some research but haven't found the optimal way to accomplish this, so would appreciate some help. My intention is to reduce the number of sql queries using lookup hashes in loop structures.

In the pseudo code below, I am fetching status codes from an sms gateway and compare those with an ActiveRecord table will all status-code descriptions.

#Status_codes in array format
status_codes = StatusCode.all

status_codes_hash = status_codes.to_array????

#Fetch delivery-status from sms gateway
response = HTTParty.get(myUrl)

response.each do |status|
if status_codes_hash[status.code]
    #Do stuff
end
end 

Upvotes: 4

Views: 9822

Answers (5)

nikolayp
nikolayp

Reputation: 17949

The shortest version for ActiveRecord:

Currency.all.map { [_1.iso_code, _1] }.to_h

returns:

=> { 'USD' => #<Currency id: 1, territory: "United States", name: "United States dollar", symbol: "$", iso_code: "USD", ...

Upvotes: 0

Mark Meeus
Mark Meeus

Reputation: 707

You can construct a Hash with an array of key value pairs like this:

Hash[/an array of key values goes here/]

So all you have to do is convert your StatusCodes to key value pairs and use it as input for Hash[]

like this

Hash[status_codes.map{|sc|[sc.code, sc]}]

Should do the trick

http://www.ruby-doc.org/core-1.9.3/Hash.html#method-c-5B-5D

Upvotes: 2

mdesantis
mdesantis

Reputation: 8517

You convert a model instance to hash via the attributes method:

StatusCode.all.map(&:attributes)
#=> [{ id: 1, code: 404, ...}, { id: 2, code: 405, ...}, ...]

Upvotes: 6

GSP
GSP

Reputation: 3789

The inject method is a convenient way to do what you're looking for, I think.

status_codes_hash = status_codes.inject({}) do |hash, obj|
  hash[obj.code] = obj
end

Upvotes: 0

KappaNossi
KappaNossi

Reputation: 2716

Use this snippet to get your hash of statuses with their codes as keys:

status_codes.group_by(&:code) 

The snippet is a shortcut for status_codes.group_by{|status| status.code}

It would also be better and more universal to check the key like this:

if status_codes_hash.has_key?(status.code)
    # do stuff
end

Upvotes: 4

Related Questions