Reputation: 6292
The model User
has first
, last
and login
as attributes. It also has a method called name
that joins first
and last
.
What I want is to iterate through the Users
records and create an array of hashes with the attributes I want. Like so:
results = []
User.all.map do |user|
record = {}
record["login"] = user.login
record["name"] = user.name
results << record
end
Is there a cleaner way in Ruby to do this?
Upvotes: 1
Views: 4591
Reputation: 44581
You can use ActiveRecord::QueryMethods#select
and ActiveRecord::Relation#as_json
:
User.select(:login, '(first || last) as name').as_json(except: :id)
Upvotes: 3
Reputation: 12906
Trying to map over User.all
is going to cause performance issues (later, if not now). To avoid instantiating all User objects, you can use pluck
to get the data directly out of the DB and then map it.
results = User.all.pluck(:login, :first, :last).map do |login, first, last|
{ 'login' => login, 'name' => first << last }
end
Instantiating all the users is going to be problematic. Even the as_json
relation method is going to do that. It may even be a problem using this method, depending on how many users there are.
Also, this assumes that User#name
really just does first + last
. If it's different, you can change the logic in the block.
Upvotes: 3
Reputation: 23317
The poorly named and poorly documented method ActiveRecord::Result#to_hash
does what you want, I think.
User.select(:login, :name).to_hash
Poorly named because it does in fact return an array of Hash, which seems pretty poor form for a method named to_hash
.
Upvotes: 0
Reputation: 106802
I would write:
results = User.all.map { |u| { login: u.login, name: u.name } }
Upvotes: 1