ActiveRecord::Relation#pluck method

This commit is contained in:
Bogdan Gusiev 2011-11-30 11:03:00 +02:00
parent d9c2882077
commit a382d60f6a
6 changed files with 62 additions and 2 deletions

View File

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

View File

@ -39,7 +39,7 @@ module ActiveRecord
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

View File

@ -449,7 +449,7 @@ module ActiveRecord #:nodoc:
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

View File

@ -166,6 +166,23 @@ module ActiveRecord
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 = {})

View File

@ -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 @@ class CalculationsTest < ActiveRecord::TestCase
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

View File

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