diff options
author | Sean Griffin <sean@seantheprogrammer.com> | 2016-01-27 23:26:34 -0500 |
---|---|---|
committer | Sean Griffin <sean@seantheprogrammer.com> | 2016-01-27 23:26:34 -0500 |
commit | 74bee8353b5189537e83043e0b78ac28c049e8e8 (patch) | |
tree | e71c62476c8e105ae6e9ec9eecc966532470a062 /activerecord/lib/active_record | |
parent | b2fe263fa66755521ba845a64dcbe3a1d86e3ff6 (diff) | |
parent | 14efb42a906aa8079adff2b1e56d6444d147a386 (diff) | |
download | rails-74bee8353b5189537e83043e0b78ac28c049e8e8.tar.gz rails-74bee8353b5189537e83043e0b78ac28c049e8e8.tar.bz2 rails-74bee8353b5189537e83043e0b78ac28c049e8e8.zip |
Merge pull request #18928 from bogdan/unreversable-order
Raise AR::IrreversibleOrderError when #reverse_order can not do it's job
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/errors.rb | 5 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/query_methods.rb | 18 |
2 files changed, 21 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb index e5906b6756..87f32c042c 100644 --- a/activerecord/lib/active_record/errors.rb +++ b/activerecord/lib/active_record/errors.rb @@ -275,4 +275,9 @@ module ActiveRecord # The mysql2 and postgresql adapters support setting the transaction isolation level. class TransactionIsolationError < ActiveRecordError end + + # IrreversibleOrderError is raised when a relation's order is too complex for + # +reverse_order+ to automatically reverse. + class IrreversibleOrderError < ActiveRecordError + end end diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 716b1e8505..8ef9f9f627 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -1104,14 +1104,21 @@ module ActiveRecord end def reverse_sql_order(order_query) - order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty? + if order_query.empty? + return [table[primary_key].desc] if primary_key + raise IrreversibleOrderError, + "Relation has no current order and table has no primary key to be used as default order" + end order_query.flat_map do |o| case o when Arel::Nodes::Ordering o.reverse when String - o.to_s.split(',').map! do |s| + if does_not_support_reverse?(o) + raise IrreversibleOrderError, "Order #{o.inspect} can not be reversed automatically" + end + o.split(',').map! do |s| s.strip! s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC') end @@ -1121,6 +1128,13 @@ module ActiveRecord end end + def does_not_support_reverse?(order) + #uses sql function with multiple arguments + order =~ /\([^()]*,[^()]*\)/ || + # uses "nulls first" like construction + order =~ /nulls (first|last)\Z/i + end + def build_order(arel) orders = order_values.uniq orders.reject!(&:blank?) |