1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Allow Enumerable#pluck to take a splat.

This allows easier integration with ActiveRecord, such that
AR#pluck will now use Enumerable#pluck if the relation is loaded,
without needing to hit the database.
This commit is contained in:
Kevin Deisz 2015-05-29 09:41:03 -04:00
parent 343dad9617
commit 777fa257aa
4 changed files with 43 additions and 2 deletions

View file

@ -161,6 +161,10 @@ module ActiveRecord
end end
end end
if loaded? && (column_names - @klass.column_names).empty?
return @records.pluck(*column_names)
end
if has_include?(column_names.first) if has_include?(column_names.first)
construct_relation_for_association_calculations.pluck(*column_names) construct_relation_for_association_calculations.pluck(*column_names)
else else

View file

@ -632,6 +632,27 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal [part.id], ShipPart.joins(:trinkets).pluck(:id) assert_equal [part.id], ShipPart.joins(:trinkets).pluck(:id)
end end
def test_pluck_loaded_relation
companies = Company.order(:id).limit(3).load
assert_no_queries do
assert_equal ['37signals', 'Summit', 'Microsoft'], companies.pluck(:name)
end
end
def test_pluck_loaded_relation_multiple_columns
companies = Company.order(:id).limit(3).load
assert_no_queries do
assert_equal [[1, '37signals'], [2, 'Summit'], [3, 'Microsoft']], companies.pluck(:id, :name)
end
end
def test_pluck_loaded_relation_sql_fragment
companies = Company.order(:id).limit(3).load
assert_queries 1 do
assert_equal ['37signals', 'Summit', 'Microsoft'], companies.pluck('DISTINCT name')
end
end
def test_grouped_calculation_with_polymorphic_relation def test_grouped_calculation_with_polymorphic_relation
part = ShipPart.create!(name: "has trinket") part = ShipPart.create!(name: "has trinket")
part.trinkets.create! part.trinkets.create!

View file

@ -76,8 +76,15 @@ module Enumerable
# #
# [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name) # [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
# => ["David", "Rafael", "Aaron"] # => ["David", "Rafael", "Aaron"]
def pluck(key) #
map { |element| element[key] } # [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name)
# => [[1, "David"], [2, "Rafael"]]
def pluck(*keys)
if keys.many?
map { |element| keys.map { |key| element[key] } }
else
map { |element| element[keys.first] }
end
end end
end end

View file

@ -3,6 +3,8 @@ require 'active_support/core_ext/array'
require 'active_support/core_ext/enumerable' require 'active_support/core_ext/enumerable'
Payment = Struct.new(:price) Payment = Struct.new(:price)
ExpandedPayment = Struct.new(:dollars, :cents)
class SummablePayment < Payment class SummablePayment < Payment
def +(p) self.class.new(price + p.price) end def +(p) self.class.new(price + p.price) end
end end
@ -114,5 +116,12 @@ class EnumerableTests < ActiveSupport::TestCase
def test_pluck def test_pluck
payments = GenericEnumerable.new([ Payment.new(5), Payment.new(15), Payment.new(10) ]) payments = GenericEnumerable.new([ Payment.new(5), Payment.new(15), Payment.new(10) ])
assert_equal [5, 15, 10], payments.pluck(:price) assert_equal [5, 15, 10], payments.pluck(:price)
payments = GenericEnumerable.new([
ExpandedPayment.new(5, 99),
ExpandedPayment.new(15, 0),
ExpandedPayment.new(10, 50)
])
assert_equal [[5, 99], [15, 0], [10, 50]], payments.pluck(:dollars, :cents)
end end
end end