Browse files

ActiveRecord::Relation#pluck method

  • Loading branch information...
1 parent d9c2882 commit a382d60f6abc94b6a965525872f858e48abc00de @bogdan bogdan committed Nov 30, 2011
@@ -1,5 +1,14 @@
## Rails 3.2.0 (unreleased) ##
+* Implemented ActiveRecord::Relation#pluck method
+ Method returns Array of column value from table under ActiveRecord model
+ Client.pluck(:id)
+ *Bogdan Gusiev*
* Automatic closure of connections in threads is deprecated. For example
the following code is deprecated:
@@ -39,7 +39,7 @@ class CollectionProxy # :nodoc:
instance_methods.each { |m| undef_method m unless m.to_s =~ /^(?:nil\?|send|object_id|to_a)$|^__|^respond_to|proxy_/ }
delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from,
- :lock, :readonly, :having, :to => :scoped
+ :lock, :readonly, :having, :pluck, :to => :scoped
delegate :target, :load_target, :loaded?, :scoped,
:to => :@association
@@ -449,7 +449,7 @@ class << self # Class methods
delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins,
:where, :preload, :eager_load, :includes, :from, :lock, :readonly,
:having, :create_with, :uniq, :to => :scoped
- delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped
+ delegate :count, :average, :minimum, :maximum, :sum, :calculate, :pluck, :to => :scoped
def inherited(child_class) #:nodoc:
# force attribute methods to be higher in inheritance hierarchy than other generated methods
@@ -166,6 +166,23 @@ def calculate(operation, column_name, options = {})
+ # This method is designed to perform select by a single column as direct SQL query
+ # Returns <tt>Array</tt> with values of the specified column name
+ # The values has same data type as column.
+ #
+ # Examples:
+ #
+ # Person.pluck(:id) # SELECT FROM people
+ # Person.uniq.pluck(:role) # SELECT DISTINCT role FROM people
+ # Person.where(:confirmed => true).limit(5).pluck(:id)
+ #
+ def pluck(column_name)
+ scope =
+ self.connection.select_values(scope.to_sql).map! do |value|
+ type_cast_using_column(value, column_for(column_name))
+ end
+ end
def perform_calculation(operation, column_name, options = {})
@@ -1,5 +1,6 @@
require "cases/helper"
require 'models/company'
+require "models/contract"
require 'models/topic'
require 'models/edge'
require 'models/club'
@@ -446,4 +447,28 @@ def test_distinct_is_honored_when_used_with_count_operation_after_group
distinct_authors_for_approved_count =, :distinct => true)[true]
assert_equal distinct_authors_for_approved_count, 2
+ def test_pluck
+ assert_equal [1,2,3,4], Topic.order(:id).pluck(:id)
+ end
+ def test_pluck_type_cast
+ topic = topics(:first)
+ relation = Topic.where(:id =>
+ assert_equal [ topic.approved ], relation.pluck(:approved)
+ assert_equal [ topic.last_read ], relation.pluck(:last_read)
+ assert_equal [ topic.written_on ], relation.pluck(:written_on)
+ end
+ def test_pluck_and_uniq
+ assert_equal [50, 53, 55, 60], Account.order(:credit_limit).uniq.pluck(:credit_limit)
+ end
+ def test_pluck_in_relation
+ company = Company.first
+ contract = company.contracts.create!
+ assert_equal [], company.contracts.pluck(:id)
+ end
@@ -1146,6 +1146,15 @@ h3. +select_all+
Client.connection.select_all("SELECT * FROM clients WHERE id = '1'")
+h3. +pluck+
+<tt>pluck</tt> can be used to query single column from table under model. It accepts column name as argument and returns Array of values of the specified column with corresponding data type.
+Client.where(:active => true).pluck(:id) # SELECT id FROM clients WHERE
+Client.uniq.pluck(:role) # SELECT DISTINCT role FROM clients
h3. Existence of Objects
If you simply want to check for the existence of the object there's a method called +exists?+. This method will query the database using the same query as +find+, but instead of returning an object or collection of objects it will return either +true+ or +false+.

46 comments on commit a382d60


+1 This looks super useful!


+1 agree

kennon commented on a382d60 Nov 30, 2011

As someone who has literally had to write ""id").collect(&:id)" four times today, this is a big +1 from me!


I've wanted a method like this for so long! I'm always writing little bits of code to do this. Thanks!

pcreux commented on a382d60 Nov 30, 2011

+1 !

Gimi commented on a382d60 Nov 30, 2011

Agree with @kennon, no'col').map(&:col) any more!


+1 Very useful!


Can't try this out at the the moment, so here's a question: How would this compare to ? Same thing / functionality?


pluck yeah ;)

pjg commented on a382d60 Nov 30, 2011

+1 really useful piece of code

anlek commented on a382d60 Nov 30, 2011

+1 ;)


Why not several columns? Wouldn't it be as useful? or am I missing something here?


+2 because it's that good

pi3r commented on a382d60 Dec 1, 2011

Thanks a lot!


Does it work with serialization like ernie/valium?


@dmitriy-kiriyenko Since no one answered my previous question about how it compares to valium, and judging by the other comments, I'd say no one here actually knew about valium.

Gimi commented on a382d60 Dec 1, 2011

@cvshepherd just got to know valium, and I think it's better.


is "pluck" really the right name for this ?

kurko commented on a382d60 Dec 1, 2011

+1: Is "pluck" really the right name for this ?


Seriously, I would propose 'project' as a better name


'project' is just as un-obvious. For a method that returns an array of columns I'd expect the method name to have something to do with getting an array of columns....

Something like 'selective_columns' and extend it to return optionally more than one column.


It's not un-obvious if you've heard of an SQL projection


values_at? =)


But I definitely like project. +1 for project.
We'll have another reserved word to avoid in business code.



kurko commented on a382d60 Dec 1, 2011

+1, but I doubt it'll be changed anyway.


Being able to "pluck" multiple columns would be quite useful as well.


+1 although I think values_at (what valium uses) would be a better name than pluck.


+1, but I actually like "pluck". It's used pretty rarely in everyday speech, and to me seeing it is odd enough that I'll remember it as a method name. -- like "tap", the other most awesome method name ever! Plus, "pluck" is such a fun word!


👍 , I actually think values_at is better than pluck or project

allochi commented on a382d60 Dec 4, 2011

+1 multiple columns


+1 multiple columns

jeremy commented on a382d60 Dec 4, 2011

bike shed


Green??? What a stupid color for a bikeshed.

But seriously, project is a better name ;)


@whitethunder, I told them, but they don't trust me. Seriously, project is an excellent name. More, I'm looking forward for a method like "user" or "company". Also a great idea would be methods "topic", "post" and "comment". =)

sj26 commented on a382d60 Dec 5, 2011


ernie commented on a382d60 Dec 5, 2011

For those who were asking, it looks like this patch handles serialized columns, because Column#type_cast decodes encoded columns in current master.

This wasn't the case in 3-0-stable, which is why Valium's implementation is (only slightly) more involved.

I agree with @jeremy, though -- this is a whole lot of discussion for a very simple change. In fact, I'd have submitted Valium's implementation as a patch long ago if I'd thought it had a chance to be accepted. One of those things where it was so ridiculously simple that I figured there was a reason it wasn't part of the AR API already. ;)

ernie commented on a382d60 Dec 5, 2011

Hmm. I take back my comment about working with serialization. It looks like the only place that a Column's coder is being set in the current AR code is in 3 tests in column_definition_test at this point, unless I missed something. It doesn't look like SchemaCache would be the right place to handle this, either.

Anyway, I have a rough version of Valium's take on this ported to a Rails 3.2 patch and passing all but the serialization tests (due to the issue mentioned). I can work out the remaining issues there and submit a value(s)_of implementation for Rails 3.2 if the core team is interested.

jeremy commented on a382d60 Dec 6, 2011

@ernie Cool, yeah, let's see it. Wish we'd known you had Valium already implemented, sorry about that. Pull request came in; didn't look for prior art. Thanks for pitching in in any case.

ernie commented on a382d60 Dec 6, 2011

@jeremy pushing it up now -- thanks!

Mab879 commented on a382d60 Dec 6, 2011


ernie commented on a382d60 Dec 6, 2011

For those visiting this thread: See #3871 for the pull request with alternate implementation supporting serialization, multiple values, etc.



ernie commented on a382d60 Dec 6, 2011

@tenderlove unicorns, rainbows and ponies would be the "etc" part

cbetta commented on a382d60 Dec 7, 2011

Love it! +1


wow, amazing +1

Please sign in to comment.