diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index b771182f96234..10c2004177f80 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,14 @@ +* Fix `QueryMethods#in_order_of` to handle empty order list. + + ```ruby + Post.in_order_of(:id, []).to_a + ``` + + Also more explicitly set the column as secondary order, so that any other + value is still ordered. + + *Jean Boussier* + * Fix quoting of column aliases generated by calculation methods. Since the alias is derived from the table name, we can't assume the result diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 447fb0545ae62..3def087ef3429 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -432,10 +432,14 @@ def in_order_of(column, values) references = column_references([column]) self.references_values |= references unless references.empty? - values = values.map { |value| type_caster.type_cast_for_database(column, value) } - column = order_column(column.to_s) if column.is_a?(Symbol) + if values.empty? + spawn.order!(column) + else + values = values.map { |value| type_caster.type_cast_for_database(column, value) } - spawn.order!(connection.field_ordered_value(column, values)) + arel_column = column.is_a?(Symbol) ? order_column(column.to_s) : column + spawn.order!(connection.field_ordered_value(arel_column, values), column) + end end # Replaces any existing order defined on the relation with the specified order. diff --git a/activerecord/test/cases/relation/field_ordered_values_test.rb b/activerecord/test/cases/relation/field_ordered_values_test.rb index fbf2b25b75ddb..90e991fb3f87d 100644 --- a/activerecord/test/cases/relation/field_ordered_values_test.rb +++ b/activerecord/test/cases/relation/field_ordered_values_test.rb @@ -14,6 +14,18 @@ def test_in_order_of 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)) + end + def test_in_order_of_with_enums_values Book.destroy_all Book.create!(status: :proposed)