diff options
author | Aaron Suggs <aaron@ktheory.com> | 2013-11-22 13:46:51 -0500 |
---|---|---|
committer | Aaron Suggs <aaron@ktheory.com> | 2013-11-22 13:46:51 -0500 |
commit | b1737337e6b6218ae966b57e9484ae7d3aaff7e4 (patch) | |
tree | f9ee849765a229b873551e4f3aa116b15510028c | |
parent | d5b71591dfa5dde3f0389ffb4e268f54334cc501 (diff) | |
download | rails-b1737337e6b6218ae966b57e9484ae7d3aaff7e4.tar.gz rails-b1737337e6b6218ae966b57e9484ae7d3aaff7e4.tar.bz2 rails-b1737337e6b6218ae966b57e9484ae7d3aaff7e4.zip |
Support SQL sanitization in AR::QueryMethods#order
Add support for sanitizing arrays in SQL ORDER clauses.
This is useful when using MySQL `ORDER BY FIELD()` to return records in
a predetermined way.
```ruby
Tag.order(['field(id, ?', [1,3,2]].to_sql
# => SELECT "tags".* FROM "tags" ORDER BY field(id, 1,3,2)
```
Prior to this, developers must be careful to sanitize `#order` arguments
themselves.
-rw-r--r-- | activerecord/lib/active_record/relation/query_methods.rb | 7 | ||||
-rw-r--r-- | activerecord/test/cases/relations_test.rb | 5 |
2 files changed, 12 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 473762011b..b676b231ec 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -1029,6 +1029,13 @@ module ActiveRecord end def preprocess_order_args(order_args) + order_args.map! do |arg| + if arg.is_a?(Array) && arg.first.to_s.include?('?') + klass.send(:sanitize_sql, arg) + else + arg + end + end order_args.flatten! validate_order_args(order_args) diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index baa3acf3fb..d408676a77 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -231,6 +231,11 @@ class RelationTest < ActiveRecord::TestCase assert_equal 3, tags.length end + def test_finding_with_sanitized_order + query = Tag.order(["field(id, ?)", [1,3,2]]).to_sql + assert_match(/field\(id, 1,3,2\)/, query) + end + def test_finding_with_order_limit_and_offset entrants = Entrant.order("id ASC").limit(2).offset(1) |