mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
QueryMethods#in_order_of
drop records not listed
`in_order_of` now filters down to the values provided, to match the behavior of the `Enumerable` version. *Kevin Newton*
This commit is contained in:
parent
6fb54c00e4
commit
e7c3219cb5
3 changed files with 20 additions and 19 deletions
|
@ -1,3 +1,9 @@
|
|||
* Change `QueryMethods#in_order_of` to drop records not listed in values.
|
||||
|
||||
`in_order_of` now filters down to the values provided, to match the behavior of the `Enumerable` version.
|
||||
|
||||
*Kevin Newton*
|
||||
|
||||
* Allow named expression indexes to be revertible.
|
||||
|
||||
Previously, the following code would raise an error in a reversible migration executed while rolling back, due to the index name not being used in the index removal.
|
||||
|
|
|
@ -432,22 +432,23 @@ module ActiveRecord
|
|||
# adapter this will either use a CASE statement or a built-in function.
|
||||
#
|
||||
# User.in_order_of(:id, [1, 5, 3])
|
||||
# # SELECT "users".* FROM "users" ORDER BY FIELD("users"."id", 1, 5, 3)
|
||||
# # SELECT "users".* FROM "users"
|
||||
# # ORDER BY FIELD("users"."id", 1, 5, 3)
|
||||
# # WHERE "users"."id" IN (1, 5, 3)
|
||||
#
|
||||
def in_order_of(column, values)
|
||||
klass.disallow_raw_sql!([column], permit: connection.column_name_with_order_matcher)
|
||||
return spawn.none! if values.empty?
|
||||
|
||||
references = column_references([column])
|
||||
self.references_values |= references unless references.empty?
|
||||
|
||||
if values.empty?
|
||||
spawn.order!(column)
|
||||
else
|
||||
values = values.map { |value| type_caster.type_cast_for_database(column, value) }
|
||||
|
||||
arel_column = column.is_a?(Symbol) ? order_column(column.to_s) : column
|
||||
spawn.order!(connection.field_ordered_value(arel_column, values), column)
|
||||
end
|
||||
|
||||
spawn
|
||||
.order!(connection.field_ordered_value(arel_column, values))
|
||||
.where!(arel_column.in(values))
|
||||
end
|
||||
|
||||
# Replaces any existing order defined on the relation with the specified order.
|
||||
|
|
|
@ -9,21 +9,15 @@ class FieldOrderedValuesTest < ActiveRecord::TestCase
|
|||
|
||||
def test_in_order_of
|
||||
order = [3, 4, 1]
|
||||
posts = Post.in_order_of(:id, order).limit(3)
|
||||
posts = Post.in_order_of(:id, order)
|
||||
|
||||
assert_equal(order, posts.map(&:id))
|
||||
end
|
||||
|
||||
def test_unspecified_order
|
||||
order = [3, 4, 1]
|
||||
post_ids = Post.in_order_of(:id, order).map(&:id)
|
||||
expected_order = order + (post_ids - order).sort
|
||||
assert_equal(expected_order, post_ids)
|
||||
end
|
||||
|
||||
def test_in_order_of_empty
|
||||
posts = Post.in_order_of(:id, [])
|
||||
assert_equal(posts.map(&:id).sort, posts.map(&:id))
|
||||
|
||||
assert_empty(posts)
|
||||
end
|
||||
|
||||
def test_in_order_of_with_enums_values
|
||||
|
@ -52,14 +46,14 @@ class FieldOrderedValuesTest < ActiveRecord::TestCase
|
|||
|
||||
def test_in_order_of_expression
|
||||
order = [3, 4, 1]
|
||||
posts = Post.in_order_of(Arel.sql("id * 2"), order.map { |id| id * 2 }).limit(3)
|
||||
posts = Post.in_order_of(Arel.sql("id * 2"), order.map { |id| id * 2 })
|
||||
|
||||
assert_equal(order, posts.map(&:id))
|
||||
end
|
||||
|
||||
def test_in_order_of_after_regular_order
|
||||
order = [3, 4, 1]
|
||||
posts = Post.where(type: "Post").order(:type).in_order_of(:id, order).limit(3)
|
||||
posts = Post.where(type: "Post").order(:type).in_order_of(:id, order)
|
||||
|
||||
assert_equal(order, posts.map(&:id))
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue