Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow order to be given expressions as hash keys #28191

Merged
merged 1 commit into from Mar 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion activerecord/lib/active_record/relation/query_methods.rb
Expand Up @@ -1130,7 +1130,12 @@ def preprocess_order_args(order_args)
arel_attribute(arg).asc
when Hash
arg.map { |field, dir|
arel_attribute(field).send(dir.downcase)
case field
when Arel::Nodes::SqlLiteral
field.send(dir.downcase)
else
arel_attribute(field).send(dir.downcase)
end
}
else
arg
Expand Down
25 changes: 24 additions & 1 deletion activerecord/test/cases/relations_test.rb
Expand Up @@ -218,17 +218,34 @@ def test_finding_with_assoc_order
assert_equal topics(:fifth).title, topics.first.title
end

def test_finding_with_reverted_assoc_order
def test_finding_with_arel_assoc_order
topics = Topic.order(Arel.sql("id") => :desc)
assert_equal 5, topics.to_a.size
assert_equal topics(:fifth).title, topics.first.title
end

def test_finding_with_reversed_assoc_order
topics = Topic.order(id: :asc).reverse_order
assert_equal 5, topics.to_a.size
assert_equal topics(:fifth).title, topics.first.title
end

def test_finding_with_reversed_arel_assoc_order
topics = Topic.order(Arel.sql("id") => :asc).reverse_order
assert_equal 5, topics.to_a.size
assert_equal topics(:fifth).title, topics.first.title
end

def test_reverse_order_with_function
topics = Topic.order("length(title)").reverse_order
assert_equal topics(:second).title, topics.first.title
end

def test_reverse_arel_assoc_order_with_function
topics = Topic.order(Arel.sql("length(title)") => :asc).reverse_order
assert_equal topics(:second).title, topics.first.title
end

def test_reverse_order_with_function_other_predicates
topics = Topic.order("author_name, length(title), id").reverse_order
assert_equal topics(:second).title, topics.first.title
Expand All @@ -251,6 +268,12 @@ def test_reverse_order_with_multiargument_function
end
end

def test_reverse_arel_assoc_order_with_multiargument_function
assert_nothing_raised do
Topic.order(Arel.sql("REPLACE(title, '', '')") => :asc).reverse_order
end
end

def test_reverse_order_with_nulls_first_or_last
assert_raises(ActiveRecord::IrreversibleOrderError) do
Topic.order("title NULLS FIRST").reverse_order
Expand Down