def jsontest
@users = User.all.limit(10)
render json: @users
end
yields
{
...
"id": 7,
"name": "Sage Smith",
"email": "[email protected]",
"created_at": "2013-10-17T02:29:15.638Z",
"updated_at": "2013-10-17T02:29:15.638Z",
"password_digest": "$2a$10$taHk3udtWN61Il5I18akj.E90AB1TmdL1BkQBKPk/4eZ7YyizGOli",
"remember_token": "118f807d0773873fb5e4cd3b5d98048aef4f6f59",
"admin": false
...
}
But I would like to omit certain certain fields from this API, so I use pluck
def jsontest
@users = User.all.limit(10).pluck(:id, :name, :email, :created_at) ###
render json: @users
end
but pluck returns an array of only values, when I would like to have each object's attributes accessible by hash key.
[
...
7,
"Sage Smith",
"[email protected]",
"2013-10-17T02:29:15.638Z"
...
]
So how can I effectively pluck the values and their keys?
I realize I could sweep through @users and grab the keys before plucking and recreate the hash, but I'm expecting there to be some convenience method that does exactly what I want.
In Rails, pluck is a shortcut to select one or more attributes without loading the corresponding records just to filter out the selected attributes. It returns an Array of attribute values.
ruby rails. Rails has a great, expressive term called pluck that allows you to grab a subset of data from a record. You can use this on ActiveRecord models to return one (or a few) columns. But you can also use the same method on regular old Enumerables to pull out all values that respond to a given key.
vee's answer is good, but I have one caveat. select
instantiates a User
for every row in the result, but pluck
does not. That doesn't matter if you are only returning a few objects, but if you are returning large batches (50, 100, etc) you'll pay a significant performance penalty.
I ran into this problem, and I switched back to pluck:
#in user.rb
def self.pluck_to_hash(*keys)
pluck(*keys).map{|pa| Hash[keys.zip(pa)]}
end
#in elsewhere.rb
User.limit(:10).pluck_to_hash(*%i[id name email created_at])
It's ugly, but it gets the hash you want, and fast.
I've updated it to reflect Mike Campbell's comment on Oct 11.
Use select
instead of pluck
:
def jsontest
@users = User.select('id, name, email, created_at').limit(10)
render json: @users
end
Created a simple pluck_to_hash
gem to achieve this.
https://github.com/girishso/pluck_to_hash
Usage example..
Post.limit(2).pluck_to_hash([:id, :title])
#
# [{:id=>213, :title=>"foo"}, {:id=>214, :title=>"bar"}]
#
Post.limit(2).pluck_to_hash(:id)
#
# [{:id=>213}, {:id=>214}]
#
# Or use the shorter alias pluck_h
Post.limit(2).pluck_h(:id)
#
# [{:id=>213}, {:id=>214}]
#
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With