pluck
can be used to query single or multiple columns from the underlying table of a model.
It accepts a list of column names as argument and returns an array of values of the specified columns with the corresponding data type.
Client.where(active: true ).pluck( :id ) # SELECT id FROM clients WHERE active = 1 # => [1, 2, 3] Client.distinct.pluck( :role ) # SELECT DISTINCT role FROM clients # => ['admin', 'member', 'guest'] Client.pluck( :id , :name ) # SELECT clients.id, clients.name FROM clients # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']] |
pluck
makes it possible to replace code like:
Client.select( :id ).map { |c| c.id } # or Client.select( :id ).map(& :id ) # or Client.select( :id , :name ).map { |c| [c.id, c.name] } |
with:
Client.pluck( :id ) # or Client.pluck( :id , :name ) |
Unlike select
, pluck
directly converts a database result into a Ruby Array
, without constructing ActiveRecord
objects. This can mean better performance for a large or often-running query. However, any model method overrides will not be available. For example:
class Client < ActiveRecord::Base def name "I am #{super}" end end Client.select( :name ).map & :name # => ["I am David", "I am Jeremy", "I am Jose"] Client.pluck( :name ) # => ["David", "Jeremy", "Jose"] |
Furthermore, unlike select
and other Relation
scopes, pluck
triggers an immediate query, and thus cannot be chained with any further scopes, although it can work with scopes already constructed earlier:
Client.pluck( :name ).limit( 1 ) # => NoMethodError: undefined method `limit' for #<Array:0x007ff34d3ad6d8> Client.limit( 1 ).pluck( :name ) # => ["David"] |