aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
authorBogdan Gusiev <agresso@gmail.com>2016-02-13 00:11:18 +0200
committerBogdan Gusiev <agresso@gmail.com>2016-02-13 10:32:51 +0200
commitb67991614349d68e0d8ad489c8c84c3254ac847b (patch)
tree92ca6e679d620987305e504c6e2f40dc668eef14 /activerecord/lib/active_record
parenta88c5ff96de98b67c75a04711847b3a29c2df411 (diff)
downloadrails-b67991614349d68e0d8ad489c8c84c3254ac847b.tar.gz
rails-b67991614349d68e0d8ad489c8c84c3254ac847b.tar.bz2
rails-b67991614349d68e0d8ad489c8c84c3254ac847b.zip
Make ActiveRecord::Relation#last to reverse SQL order
instead of loading the relation into memory
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb28
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb2
2 files changed, 21 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index a4280c5f33..ba64e3ca60 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -145,15 +145,21 @@ module ActiveRecord
#
# [#<Person id:4>, #<Person id:3>, #<Person id:2>]
def last(limit = nil)
- if limit
- if order_values.empty? && primary_key
- order(arel_attribute(primary_key).desc).limit(limit).reverse
- else
- to_a.last(limit)
- end
- else
- find_last
- end
+ return find_last(limit) if loaded? || limit_value
+
+ result = limit(limit || 1)
+ result.order!(arel_attribute(primary_key)) if order_values.empty? && primary_key
+ result = result.reverse_order!
+
+ limit ? result.reverse : result.first
+ rescue ActiveRecord::IrreversibleOrderError
+ ActiveSupport::Deprecation.warn(<<-WARNING.squish)
+ Finding a last element by loading the relation when SQL ORDER
+ can not be reversed is deprecated.
+ Rails 5.1 will raise ActiveRecord::IrreversibleOrderError in this case.
+ Please call `to_a.last` if you still want to load the relation.
+ WARNING
+ find_last(limit)
end
# Same as #last but raises ActiveRecord::RecordNotFound if no record
@@ -578,5 +584,9 @@ module ActiveRecord
find_nth_with_limit(index, limit)
end
end
+
+ def find_last(limit)
+ limit ? to_a.last(limit) : to_a.last
+ end
end
end
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 91bfa4d131..91d486e902 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -1112,6 +1112,8 @@ module ActiveRecord
order_query.flat_map do |o|
case o
+ when Arel::Attribute
+ o.desc
when Arel::Nodes::Ordering
o.reverse
when String