Build Hash from Collection of Activerecord Models

Build hash from collection of ActiveRecord Models

Here are some one-liner alternatives:

# Ruby 2.1+
name_to_code = countries.map{ |c| [c.name,c.code] }.to_h

# Ruby 1.8.7+
name_to_code = Hash[ countries.map{ |c| [c.name,c.code] } ]

# Ruby 1.8.6+
name_to_code = Hash[ *countries.map{ |c| [c.name,c.code] }.flatten ]

# Ruby 1.9+
name_to_code = {}.tap{ |h| countries.each{ |c| h[c.name] = c.code } }

# Ruby 1.9+
name_to_code = countries.to_a.each_with_object({}){ |c,h| h[c.name] = c.code }

Courtesy of @Addicted's comment below:

# Ruby 1.8+
name_to_code = countries.inject({}){ |r,c| r.merge c.name=>c.code }

make a hash from active records

So given the fact that this is ActiveRecord data to begin with why not something like

data = Model.group(:name,:date).order(name: :asc, date: :asc).sum(:count)
data.each_with_object(Hash.new {|h,k| h[k] = []}) do |((name,date),count),obj|
obj[name] << {date: date, count: count}
end

This will produce:

{
"a"=>[{:date=>20190702, :count=>0}, {:date=>20190703, :count=>20}],
"b"=>[{:date=>20190702, :count=>10}],
"c"=>[{:date=>20190702, :count=>8}, {:date=>20190703, :count=>20}]
}

and all of the summing and grouping is placed on the SQL side of things (which is very efficient at aggregation)

Rails create hash for each new model created

If you're looking for a persistent unique hash, you could add a column called unique_id and do something like:

class Foo < ActiveRecord::Base
before_save :generate_unique_id

def generate_unique_id
# generate a random hex string using trickery:
self.unique_id = rand(36**12).to_s(16) # => "22b0433e3d9ae776"
# generate a 12-char random string a-z0-9:
self.unique_id = rand(36**12).to_s(36) # => "os0w9cl8xi48"
# or, if you want to do something more obvious:
self.unique_id = SecureRandom.hex(6) # => "ba191acc80ef"
# or, if you want a legitimate UUID:
self.unique_id = SecureRandom.uuid # => "72569edd-1841-4fd9-af05-edf66a58b74b"
end
end

Build hash index from collection in ruby

Here is what I ended up doing

body = { 
transaction: {
amount:"45.55",
currency:"CAD",
}
}

items_hash = {}
items.each_with_index do |item, index|
h = { "#{index}" => { sku: item.sku } }
items_hash.merge!(h)
end

details = { "transaction_detail" => items_hash }

hash = hash.merge!(details)
hash.to_json

Rails Object to hash

If you are looking for only attributes, then you can get them by:

@post.attributes

Note that this calls ActiveModel::AttributeSet.to_hash every time you invoke it, so if you need to access the hash multiple times you should cache it in a local variable:

attribs = @post.attributes

Fetch ActiveRecord model for each key in array of hashes

First of all, I would find the comments matching the comment IDs, but also includes(:user) (see Rails eager loading guide) so that we can get the user associated with a comment without needing an additional query:

comments = Comment.where(id: comment_ids).includes(:user)

From this point there are two ways you can go about things. First Enumerable#find (different than ActiveRecord::Base#find, by the way) to pick out the comment corresponding to a particular id, and then read the user from that comment record

arr.each do |h|
comment = comments.find { |comment| comment.id == h[:comment_id] }
h[:user] = comment.user
end

Another way is to use some enumerable manipulation to create a hash where keys are comment IDs, and values are user objects. See index_by and transform_values

users_by_comment_id = comments.index_by(&:id).transform_values(&:user)

arr.each do |h|
h[:user] = users_by_comment_id[h[:comment_id]]
end

Convert Active Record Object into Hash

You can get it from below query,

Hash[Person.all.collect { |user| [user.email, user.attributes.except(:email).values] }]

If you want to omit other attributes like created_at & updated_at, run

Hash[Person.all.collect { |user| [user.email, user.attributes.except(:email, :created_at, :updated_at).values] }]


Related Topics



Leave a reply



Submit