diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index a135b3c91f7aada139615c6c2f824994216f678e..3fbf043c7c7b5f66075514bab3266b652ed61eac 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -4,6 +4,15 @@ *Hiroshige UMINO* +* Fix when performing an ordered join query. The bug only + affected queries where the order was given with a symbol. + Fixes #9275. + + Example: + + # This will expand the order :name to "authors".name. + Author.joins(:books).where('books.published = 1').order(:name) + * Fixing issue #8345. Now throwing an error when one attempts to touch a new object that has not yet been persisted. For instance: diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 225677085f626fae2498890e1d772a2914b51e2f..4b8c40592e12e5ba66e91ec33188bb17a65f2d6e 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -285,6 +285,11 @@ def order!(*args) # :nodoc: references.map! { |arg| arg =~ /^([a-zA-Z]\w*)\.(\w+)/ && $1 }.compact! references!(references) if references.any? + # if a symbol is given we prepend the quoted table name + args = args.map { |arg| + arg.is_a?(Symbol) ? "#{quoted_table_name}.#{arg} ASC" : arg + } + self.order_values = args + self.order_values self end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 6ed3cb7b585c1221f7712687e7c62418c5653988..1de7ee084642d435576962c3606d3d4a52832bf5 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -1173,4 +1173,9 @@ def test_deep_including_through_habtm assert_no_queries { assert_equal 2, author.comments_with_order_and_conditions.size } assert_no_queries { assert_equal 5, author.posts.size, "should not cache a subset of the association" } end + + test "works in combination with order(:symbol)" do + author = Author.includes(:posts).references(:posts).order(:name).where('posts.title IS NOT NULL').first + assert_equal authors(:bob), author + end end diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index 92dc575d372c78bfdd6c6d5858430aca5ff8acf0..fd0b05cb77598a1f61b92920002ca38b0ba4b2c0 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -180,19 +180,32 @@ def test_references_values_dont_duplicate class RelationMutationTest < ActiveSupport::TestCase class FakeKlass < Struct.new(:table_name, :name) + def quoted_table_name + %{"#{table_name}"} + end end def relation - @relation ||= Relation.new FakeKlass, :b + @relation ||= Relation.new FakeKlass.new('posts'), :b end - (Relation::MULTI_VALUE_METHODS - [:references, :extending]).each do |method| + (Relation::MULTI_VALUE_METHODS - [:references, :extending, :order]).each do |method| test "##{method}!" do assert relation.public_send("#{method}!", :foo).equal?(relation) assert_equal [:foo], relation.public_send("#{method}_values") end end + test "#order!" do + assert relation.order!('name ASC').equal?(relation) + assert_equal ['name ASC'], relation.order_values + end + + test "#order! with symbol prepends the table name" do + assert relation.order!(:name).equal?(relation) + assert_equal ['"posts".name ASC'], relation.order_values + end + test '#references!' do assert relation.references!(:foo).equal?(relation) assert relation.references_values.include?('foo')