diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 8f7f30167d054a4fcc57a75e0ba257ea1d822554..70d7988e94965e3ff343d393c988f5b275bea30e 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,18 @@ +* Revert `ActiveRecord::Relation#order` change that make new order + prepend the old one. + + Before: + + User.order("name asc").order("created_at desc") + # SELECT * FROM users ORDER BY created_at desc, name asc + + After: + + User.order("name asc").order("created_at desc") + # SELECT * FROM users ORDER BY name asc, created_at desc + + This also affects order defined in `default_scope` or any kind of associations. + * Add ability to define how a class is converted to Arel predicates. For example, adding a very vendor specific regex implementation: diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index d0c56ac3d0428b9b008b4e46cab7c36fb64e0626..49b632c4c7c82b20ff6670961832cab91ce14ef0 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -299,7 +299,7 @@ def order!(*args) # :nodoc: arg } - self.order_values = args.concat self.order_values + self.order_values += args self end @@ -311,7 +311,7 @@ def order!(*args) # :nodoc: # # User.order('email DESC').reorder('id ASC').order('name ASC') # - # generates a query with 'ORDER BY name ASC, id ASC'. + # generates a query with 'ORDER BY id ASC, name ASC'. def reorder(*args) check_if_method_has_arguments!("reorder", args) spawn.reorder!(*args) diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index c63f48e370847a1ed3e6fca00443ce7a26dbafd9..712a77013333e5a81435a4f5a80b00077dde62f8 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -506,9 +506,9 @@ def test_dynamic_find_should_respect_association_order assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis') end - def test_find_should_prepend_to_association_order + def test_find_should_append_to_association_order ordered_developers = projects(:active_record).developers.order('projects.id') - assert_equal ['projects.id', 'developers.name desc, developers.id desc'], ordered_developers.order_values + assert_equal ['developers.name desc, developers.id desc', 'projects.id'], ordered_developers.order_values end def test_dynamic_find_all_should_respect_readonly_access diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 9c484a8bbedef8e5747066d624ee218e4f935312..ce51853bf31d2e06240cf6d3b70576d70ee37a41 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -253,9 +253,9 @@ def test_find_many_with_merged_options assert_equal 2, companies(:first_firm).limited_clients.limit(nil).to_a.size end - def test_find_should_prepend_to_association_order + def test_find_should_append_to_association_order ordered_clients = companies(:first_firm).clients_sorted_desc.order('companies.id') - assert_equal ['companies.id', 'id DESC'], ordered_clients.order_values + assert_equal ['id DESC', 'companies.id'], ordered_clients.order_values end def test_dynamic_find_should_respect_association_order diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index d0f8731b9a9f33032f36822d9dbb19ced04fed69..bf9d395b2dd62f168fd63e3af92d38e8f633fdeb 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -180,7 +180,7 @@ def test_finding_last_with_arel_order end def test_finding_with_order_concatenated - topics = Topic.order('title').order('author_name') + topics = Topic.order('author_name').order('title') assert_equal 4, topics.to_a.size assert_equal topics(:fourth).title, topics.first.title end @@ -1183,20 +1183,20 @@ def test_order_by_relation_attribute end def test_default_scope_order_with_scope_order - assert_equal 'honda', CoolCar.order_using_new_style.limit(1).first.name - assert_equal 'honda', FastCar.order_using_new_style.limit(1).first.name + assert_equal 'zyke', CoolCar.order_using_new_style.limit(1).first.name + assert_equal 'zyke', FastCar.order_using_new_style.limit(1).first.name end def test_order_using_scoping car1 = CoolCar.order('id DESC').scoping do - CoolCar.all.merge!(:order => 'id asc').first + CoolCar.all.merge!(order: 'id asc').first end - assert_equal 'honda', car1.name + assert_equal 'zyke', car1.name car2 = FastCar.order('id DESC').scoping do - FastCar.all.merge!(:order => 'id asc').first + FastCar.all.merge!(order: 'id asc').first end - assert_equal 'honda', car2.name + assert_equal 'zyke', car2.name end def test_unscoped_block_style diff --git a/activerecord/test/cases/scoping/default_scoping_test.rb b/activerecord/test/cases/scoping/default_scoping_test.rb index 4bcc97ec44872b6edf3dbd93862662f09234ffd6..2358e2396d2e536df668d0d12614726976b3e828 100644 --- a/activerecord/test/cases/scoping/default_scoping_test.rb +++ b/activerecord/test/cases/scoping/default_scoping_test.rb @@ -82,7 +82,7 @@ def test_default_scope_with_multiple_calls end def test_scope_overwrites_default - expected = Developer.all.merge!(:order => ' name DESC, salary DESC').to_a.collect { |dev| dev.name } + expected = Developer.all.merge!(order: 'salary DESC, name DESC').to_a.collect { |dev| dev.name } received = DeveloperOrderedBySalary.by_name.to_a.collect { |dev| dev.name } assert_equal expected, received end @@ -94,7 +94,7 @@ def test_reorder_overrides_default_scope_order end def test_order_after_reorder_combines_orders - expected = Developer.order('id DESC, name DESC').collect { |dev| [dev.name, dev.id] } + expected = Developer.order('name DESC, id DESC').collect { |dev| [dev.name, dev.id] } received = Developer.order('name ASC').reorder('name DESC').order('id DESC').collect { |dev| [dev.name, dev.id] } assert_equal expected, received end @@ -253,8 +253,8 @@ def test_unscope_errors_with_non_symbol_or_hash_arguments end def test_order_in_default_scope_should_not_prevail - expected = Developer.all.merge!(:order => 'salary').to_a.collect { |dev| dev.salary } - received = DeveloperOrderedBySalary.all.merge!(:order => 'salary').to_a.collect { |dev| dev.salary } + expected = Developer.all.merge!(order: 'salary desc').to_a.collect { |dev| dev.salary } + received = DeveloperOrderedBySalary.all.merge!(order: 'salary').to_a.collect { |dev| dev.salary } assert_equal expected, received end diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 9252a248b2f9601540278456058d18f5762bcd2d..7fe9b8b4af3a322ae642600cbf08fe84197b822f 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -549,11 +549,11 @@ Client.order("orders_count ASC, created_at DESC") Client.order("orders_count ASC", "created_at DESC") ``` -If you want to call `order` multiple times e.g. in different context, new order will prepend previous one +If you want to call `order` multiple times e.g. in different context, new order will append previous one ```ruby Client.order("orders_count ASC").order("created_at DESC") -# SELECT * FROM clients ORDER BY created_at DESC, orders_count ASC +# SELECT * FROM clients ORDER BY orders_count ASC, created_at DESC ``` Selecting Specific Fields diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 656e6d99563a1545eee2eed682ecbbe2b2fbe13d..73c783085e995ea69023b508ef882b1ed15b4fae 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -153,8 +153,6 @@ Rails 4.0 no longer supports loading plugins from `vendor/plugins`. You must rep * In Rails 4.0 when a column or a table is renamed the related indexes are also renamed. If you have migrations which rename the indexes, they are no longer needed. -* Rails 4.0 has changed how orders get stacked in `ActiveRecord::Relation`. In previous versions of Rails, the new order was applied after the previously defined order. But this is no longer true. Check [Active Record Query guide](active_record_querying.html#ordering) for more information. - * Rails 4.0 has changed `serialized_attributes` and `attr_readonly` to class methods only. You shouldn't use instance methods since it's now deprecated. You should change them to use class methods, e.g. `self.serialized_attributes` to `self.class.serialized_attributes`. * Rails 4.0 has removed `attr_accessible` and `attr_protected` feature in favor of Strong Parameters. You can use the [Protected Attributes gem](https://github.com/rails/protected_attributes) for a smooth upgrade path.