Permalink
Browse files

ActiveRecord::Relation#pluck method

  • Loading branch information...
bogdan committed Nov 30, 2011
1 parent d9c2882 commit a382d60f6abc94b6a965525872f858e48abc00de
@@ -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 = {})
0
end
# 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 people.id 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.select(column_name)
self.connection.select_values(scope.to_sql).map! do |value|
type_cast_using_column(value, column_for(column_name))
end
end
private
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 = Topic.group(:approved).count(:author_name, :distinct => true)[true]
assert_equal distinct_authors_for_approved_count, 2
end
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 => topic.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 [contract.id], company.contracts.pluck(:id)
end
end
@@ -1146,6 +1146,15 @@ h3. +select_all+
Client.connection.select_all("SELECT * FROM clients WHERE id = '1'")
</ruby>
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.
<ruby>
Client.where(:active => true).pluck(:id) # SELECT id FROM clients WHERE clients.active
Client.uniq.pluck(:role) # SELECT DISTINCT role FROM clients
</ruby>
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

@jtmkrueger

This comment has been minimized.

Show comment
Hide comment
@jtmkrueger

jtmkrueger Nov 30, 2011

+1 This looks super useful!

jtmkrueger replied Nov 30, 2011

+1 This looks super useful!

@ahawkins

This comment has been minimized.

Show comment
Hide comment
@ahawkins

ahawkins replied Nov 30, 2011

+1 agree

@kennon

This comment has been minimized.

Show comment
Hide comment
@kennon

kennon Nov 30, 2011

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

kennon replied Nov 30, 2011

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

@brycethornton

This comment has been minimized.

Show comment
Hide comment
@brycethornton

brycethornton Nov 30, 2011

Contributor

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

Contributor

brycethornton replied Nov 30, 2011

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

@pcreux

This comment has been minimized.

Show comment
Hide comment
@pcreux

pcreux Nov 30, 2011

Contributor

+1 !

Contributor

pcreux replied Nov 30, 2011

+1 !

@Gimi

This comment has been minimized.

Show comment
Hide comment
@Gimi

Gimi Nov 30, 2011

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

Gimi replied Nov 30, 2011

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

@crjones

This comment has been minimized.

Show comment
Hide comment
@crjones

crjones Nov 30, 2011

+1 Very useful!

crjones replied Nov 30, 2011

+1 Very useful!

@cvshepherd

This comment has been minimized.

Show comment
Hide comment
@cvshepherd

cvshepherd Nov 30, 2011

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

cvshepherd replied Nov 30, 2011

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

@subdigital

This comment has been minimized.

Show comment
Hide comment
@subdigital

subdigital Nov 30, 2011

Contributor

pluck yeah ;)

Contributor

subdigital replied Nov 30, 2011

pluck yeah ;)

@pjg

This comment has been minimized.

Show comment
Hide comment
@pjg

pjg Nov 30, 2011

Contributor

+1 really useful piece of code

Contributor

pjg replied Nov 30, 2011

+1 really useful piece of code

@anlek

This comment has been minimized.

Show comment
Hide comment
@anlek

anlek replied Nov 30, 2011

+1 ;)

@guimello

This comment has been minimized.

Show comment
Hide comment
@guimello

guimello Nov 30, 2011

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

guimello replied Nov 30, 2011

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

@evilmarty

This comment has been minimized.

Show comment
Hide comment
@evilmarty

evilmarty Dec 1, 2011

+2 because it's that good

evilmarty replied Dec 1, 2011

+2 because it's that good

@pi3r

This comment has been minimized.

Show comment
Hide comment
@pi3r

pi3r Dec 1, 2011

Thanks a lot!

pi3r replied Dec 1, 2011

Thanks a lot!

@dmitriy-kiriyenko

This comment has been minimized.

Show comment
Hide comment
@dmitriy-kiriyenko

dmitriy-kiriyenko Dec 1, 2011

Contributor

Does it work with serialization like ernie/valium?

Contributor

dmitriy-kiriyenko replied Dec 1, 2011

Does it work with serialization like ernie/valium?

@cvshepherd

This comment has been minimized.

Show comment
Hide comment
@cvshepherd

cvshepherd Dec 1, 2011

@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.

cvshepherd replied Dec 1, 2011

@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

This comment has been minimized.

Show comment
Hide comment
@Gimi

Gimi Dec 1, 2011

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

Gimi replied Dec 1, 2011

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

@defsdoor

This comment has been minimized.

Show comment
Hide comment
@defsdoor

defsdoor Dec 1, 2011

is "pluck" really the right name for this ?

defsdoor replied Dec 1, 2011

is "pluck" really the right name for this ?

@kurko

This comment has been minimized.

Show comment
Hide comment
@kurko

kurko Dec 1, 2011

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

kurko replied Dec 1, 2011

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

@whitethunder

This comment has been minimized.

Show comment
Hide comment
@whitethunder

whitethunder Dec 1, 2011

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

whitethunder replied Dec 1, 2011

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

@defsdoor

This comment has been minimized.

Show comment
Hide comment
@defsdoor

defsdoor Dec 1, 2011

'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.

defsdoor replied Dec 1, 2011

'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.

@whitethunder

This comment has been minimized.

Show comment
Hide comment
@whitethunder

whitethunder Dec 1, 2011

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

whitethunder replied Dec 1, 2011

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

@dmitriy-kiriyenko

This comment has been minimized.

Show comment
Hide comment
@dmitriy-kiriyenko

dmitriy-kiriyenko Dec 1, 2011

Contributor

values_at? =)

Contributor

dmitriy-kiriyenko replied Dec 1, 2011

values_at? =)

@dmitriy-kiriyenko

This comment has been minimized.

Show comment
Hide comment
@dmitriy-kiriyenko

dmitriy-kiriyenko Dec 1, 2011

Contributor

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

Contributor

dmitriy-kiriyenko replied Dec 1, 2011

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

@jweslley

This comment has been minimized.

Show comment
Hide comment
@jweslley

jweslley replied Dec 1, 2011

+1

@kurko

This comment has been minimized.

Show comment
Hide comment
@kurko

kurko Dec 1, 2011

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

kurko replied Dec 1, 2011

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

@ckknight

This comment has been minimized.

Show comment
Hide comment
@ckknight

ckknight Dec 2, 2011

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

ckknight replied Dec 2, 2011

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

@mariovisic

This comment has been minimized.

Show comment
Hide comment
@mariovisic

mariovisic Dec 3, 2011

Contributor

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

Contributor

mariovisic replied Dec 3, 2011

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

@sinisterchipmunk

This comment has been minimized.

Show comment
Hide comment
@sinisterchipmunk

sinisterchipmunk Dec 3, 2011

Contributor

+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!

Contributor

sinisterchipmunk replied Dec 3, 2011

+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!

@leomao10

This comment has been minimized.

Show comment
Hide comment
@leomao10

leomao10 Dec 4, 2011

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

leomao10 replied Dec 4, 2011

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

@allochi

This comment has been minimized.

Show comment
Hide comment
@allochi

allochi Dec 4, 2011

+1 multiple columns

allochi replied Dec 4, 2011

+1 multiple columns

@mcmorgan

This comment has been minimized.

Show comment
Hide comment
@mcmorgan

mcmorgan Dec 4, 2011

Contributor

+1 multiple columns

Contributor

mcmorgan replied Dec 4, 2011

+1 multiple columns

@jeremy

This comment has been minimized.

Show comment
Hide comment
@jeremy
Member

jeremy replied Dec 4, 2011

bike shed

@whitethunder

This comment has been minimized.

Show comment
Hide comment
@whitethunder

whitethunder Dec 4, 2011

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

But seriously, project is a better name ;)

whitethunder replied Dec 4, 2011

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

But seriously, project is a better name ;)

@dmitriy-kiriyenko

This comment has been minimized.

Show comment
Hide comment
@dmitriy-kiriyenko

dmitriy-kiriyenko Dec 4, 2011

Contributor

@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". =)

Contributor

dmitriy-kiriyenko replied Dec 4, 2011

@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

This comment has been minimized.

Show comment
Hide comment
@sj26

sj26 Dec 5, 2011

Contributor

👍

Contributor

sj26 replied Dec 5, 2011

👍

@ernie

This comment has been minimized.

Show comment
Hide comment
@ernie

ernie Dec 5, 2011

Contributor

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. ;)

Contributor

ernie replied 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

This comment has been minimized.

Show comment
Hide comment
@ernie

ernie Dec 5, 2011

Contributor

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.

Contributor

ernie replied 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

This comment has been minimized.

Show comment
Hide comment
@jeremy

jeremy Dec 6, 2011

Member

@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.

Member

jeremy replied 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

This comment has been minimized.

Show comment
Hide comment
@ernie

ernie Dec 6, 2011

Contributor

@jeremy pushing it up now -- thanks!

Contributor

ernie replied Dec 6, 2011

@jeremy pushing it up now -- thanks!

@Mab879

This comment has been minimized.

Show comment
Hide comment
@Mab879

Mab879 replied Dec 6, 2011

👍

@ernie

This comment has been minimized.

Show comment
Hide comment
@ernie

ernie Dec 6, 2011

Contributor

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

Contributor

ernie replied Dec 6, 2011

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

@tenderlove

This comment has been minimized.

Show comment
Hide comment
@tenderlove
Member

tenderlove replied Dec 6, 2011

unicorn

@ernie

This comment has been minimized.

Show comment
Hide comment
@ernie

ernie Dec 6, 2011

Contributor

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

Contributor

ernie replied Dec 6, 2011

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

@cbetta

This comment has been minimized.

Show comment
Hide comment
@cbetta

cbetta Dec 7, 2011

Love it! +1

cbetta replied Dec 7, 2011

Love it! +1

@fmquaglia

This comment has been minimized.

Show comment
Hide comment
@fmquaglia

fmquaglia Jan 4, 2012

wow, amazing +1

fmquaglia replied Jan 4, 2012

wow, amazing +1

Please sign in to comment.