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.
Usage
In Rails, use pluck
to query a subset of columns.
Shoe.all.map(&:name) # SELECT "shoes.*" from "shoes" # => ["Air Force 1", "NMD_2", "Air Jordans", ...] # This returns an array with all shoe names, but our database query pulled down all of the columns on the `shoes` table Shoe.pluck(:name) # SELECT "shoes.name" from "shoes" # => ["Air Force 1", "NMD_2", "Air Jordans", ...] # Same result, but we only query exactly the columns we wanted Shoe.pluck(:name, :brand) # SELECT "shoes"."name", "shoes"."brand" FROM "shoes" # => [["Air Jordan 1 Mid", "Nike"], ["Air Jordan 1 Mid", "Nike"], ... ] Shoe.distinct.pluck(:brand) # SELECT DISTINCT "shoes"."brand" FROM "shoes" # => ["Nike", "Adidas", ...]
You can also use pluck
with Enumerables
when using ActiveSupport
:
[ { id: 1, name: "David" }, { id: 2, name: "Rafael" }, { id: 3, name: "Aaron" } ].pluck(:name) # => ["David", "Rafael", "Aaron"]
I find the Enumerable
version to be particularly handy when dealing with JSON data from external APIs.
require "httparty" require "active_support" require "active_support/core_ext" response = HTTParty.get('http://api.stackexchange.com/2.2/questions?site=stackoverflow') questions = JSON.parse(response.body)["items"] questions.pluck("title") # => [ # "JavaScript to Python - Interpreting JavasScript .filter() to a Python user", # "Nuxt generate and firebase gives timer warning", # "Variable expected error when I increment the value of a map", # ... # ]
While pluck
is most often used with Hashes, you can use it with any object that responds to the message you pass in – including regular Ruby objects or Structs.
Next time you find yourself calling map
to get back a single value, see if your code might be improved by switching to pluck
.
Additional Resources
Rails API Docs: ActiveRecord#pluck
Rails API Docs: Enumerable#pluck
Top comments (1)
If you're a Sequel user, try #get to "pluck" the first matching record in a dataset. For example,
Shoe[params[:id]].get(:name)
.