Browse files

Expand order(:symbol) to "table".symbol to prevent broken queries on PG.

Fixes #9275.

When `#order` is called with a Symbol this patch will prepend the quoted_table_name.
Before the postgresql adapter failed to build queries containg a join and an order
with a symbol.

This expansion happens for all adapters.
  • Loading branch information...
1 parent 45321a6 commit e0356990856abc9a84e6e038e7b06e2931502728 @senny senny committed Feb 25, 2013
View
9 activerecord/CHANGELOG.md
@@ -1,5 +1,14 @@
## Rails 4.0.0 (unreleased) ##
+* 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:
View
5 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
@tenderlove
Ruby on Rails member
tenderlove added a line comment Jul 15, 2013

Hi, I'd like to avoid slapping together SQL string literals if possible please. If you're writing SQL literal strings, please think twice.

I've removed the SQL literal here: d345ed4

@senny
Ruby on Rails member
senny added a line comment Jul 16, 2013

@tenderlove Thanks for the fix and letting me know. ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+
self.order_values = args + self.order_values
self
end
View
7 activerecord/test/cases/associations/eager_test.rb
@@ -218,7 +218,7 @@ def test_finding_with_includes_on_belongs_to_association_with_same_include_inclu
def test_finding_with_includes_on_null_belongs_to_association_with_same_include_includes_only_once
post = posts(:welcome)
post.update!(author: nil)
- post = assert_queries(1) { Post.all.merge!(includes: {author_with_address: :author_address}).find(post.id) }
+ post = assert_queries(1) { Post.all.merge!(includes: {author_with_address: :author_address}).find(post.id) }
# find the post, then find the author which is null so no query for the author or address
assert_no_queries do
assert_equal nil, post.author_with_address
@@ -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
View
17 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')

0 comments on commit e035699

Please sign in to comment.