mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Enumerable#in_order_of (#41333)
* Add Enumerable#in_order_of * Explain behavior further * Use Enumerable#in_order_of * Use Ruby 2.7 #filter_map * Update activesupport/lib/active_support/core_ext/enumerable.rb Co-authored-by: Jonathan Hefner <jonathan@hefner.pro> * No need for explaining variable * Add CHANGELOG entry Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
This commit is contained in:
parent
9e8824036d
commit
9cb09411e1
4 changed files with 32 additions and 4 deletions
|
@ -520,10 +520,7 @@ module ActiveRecord
|
|||
result = except(:limit, :offset).where(primary_key => ids).records
|
||||
|
||||
if result.size == ids.size
|
||||
pk_type = @klass.type_for_attribute(primary_key)
|
||||
|
||||
records_by_id = result.index_by(&:id)
|
||||
ids.map { |id| records_by_id.fetch(pk_type.cast(id)) }
|
||||
result.in_order_of(:id, ids.map { |id| @klass.type_for_attribute(primary_key).cast(id) })
|
||||
else
|
||||
raise_record_not_found_exception!(ids, result.size, ids.size)
|
||||
end
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
* Add `Enumerable#in_order_of` to put an Enumerable in a certain order by a key.
|
||||
|
||||
*DHH*
|
||||
|
||||
* `ActiveSupport::Inflector.camelize` behaves expected when provided a symbol `:upper` or `:lower` argument. Matches
|
||||
`String#camelize` behavior.
|
||||
|
||||
|
|
|
@ -191,6 +191,18 @@ module Enumerable
|
|||
def compact_blank
|
||||
reject(&:blank?)
|
||||
end
|
||||
|
||||
# Returns a new +Array+ where the order has been set to that provided in the +series+, based on the +key+ of the
|
||||
# objects in the original enumerable.
|
||||
#
|
||||
# [ Person.find(5), Person.find(3), Person.find(1) ].in_order_of(:id, [ 1, 5, 3 ])
|
||||
# => [ Person.find(1), Person.find(5), Person.find(3) ]
|
||||
#
|
||||
# If the +series+ include keys that have no corresponding element in the Enumerable, these are ignored.
|
||||
# If the Enumerable has additional elements that aren't named in the +series+, these are not included in the result.
|
||||
def in_order_of(key, series)
|
||||
index_by(&key).values_at(*series).compact
|
||||
end
|
||||
end
|
||||
|
||||
class Hash
|
||||
|
|
|
@ -284,4 +284,19 @@ class EnumerableTests < ActiveSupport::TestCase
|
|||
values.compact_blank!
|
||||
assert_equal({ b: 1, f: true }, values)
|
||||
end
|
||||
|
||||
def test_in_order_of
|
||||
values = [ Payment.new(5), Payment.new(1), Payment.new(3) ]
|
||||
assert_equal [ Payment.new(1), Payment.new(5), Payment.new(3) ], values.in_order_of(:price, [ 1, 5, 3 ])
|
||||
end
|
||||
|
||||
def test_in_order_of_ignores_missing_series
|
||||
values = [ Payment.new(5), Payment.new(1), Payment.new(3) ]
|
||||
assert_equal [ Payment.new(1), Payment.new(5), Payment.new(3) ], values.in_order_of(:price, [ 1, 2, 4, 5, 3 ])
|
||||
end
|
||||
|
||||
def test_in_order_of_drops_elements_not_named_in_series
|
||||
values = [ Payment.new(5), Payment.new(1), Payment.new(3) ]
|
||||
assert_equal [ Payment.new(1), Payment.new(5) ], values.in_order_of(:price, [ 1, 5 ])
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue