diff options
author | Matthew Draper <matthew@trebex.net> | 2016-03-02 02:28:17 +1030 |
---|---|---|
committer | Matthew Draper <matthew@trebex.net> | 2016-03-02 02:28:17 +1030 |
commit | ecdc0fbc872ea734adf29b3f9f3463b916235286 (patch) | |
tree | 5ee8f81bf20f1e8ecd62e387d783143a7e7183d6 /activerecord/lib/active_record | |
parent | 833b14c8f8cae2f2ad2ea31669380b51e644c7db (diff) | |
parent | f9ddfc3b4b2ab6eebaa4ddb33347e715e3a82375 (diff) | |
download | rails-ecdc0fbc872ea734adf29b3f9f3463b916235286.tar.gz rails-ecdc0fbc872ea734adf29b3f9f3463b916235286.tar.bz2 rails-ecdc0fbc872ea734adf29b3f9f3463b916235286.zip |
Merge pull request #23598 from brchristian/activerecord_second_to_last
ActiveRecord #second_to_last tests and finder methods
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/relation/finder_methods.rb | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 0037398554..c3053f0b13 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -255,13 +255,13 @@ module ActiveRecord # Person.offset(3).third_to_last # returns the third-to-last object from OFFSET 3 # Person.where(["user_name = :u", { u: user_name }]).third_to_last def third_to_last - find_nth(-3) + find_nth_from_last 3 end # Same as #third_to_last but raises ActiveRecord::RecordNotFound if no record # is found. def third_to_last! - find_nth!(-3) + find_nth_from_last 3 or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql(@klass.arel_engine)}]") end # Find the second-to-last record. @@ -271,13 +271,13 @@ module ActiveRecord # Person.offset(3).second_to_last # returns the second-to-last object from OFFSET 3 # Person.where(["user_name = :u", { u: user_name }]).second_to_last def second_to_last - find_nth(-2) + find_nth_from_last 2 end # Same as #second_to_last but raises ActiveRecord::RecordNotFound if no record # is found. def second_to_last! - find_nth!(-2) + find_nth_from_last 2 or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql(@klass.arel_engine)}]") end # Returns true if a record exists in the table that matches the +id+ or @@ -561,6 +561,25 @@ module ActiveRecord relation.limit(limit).to_a end + def find_nth_from_last(index) + if loaded? + @records[-index] + else + relation = if order_values.empty? && primary_key + order(arel_attribute(primary_key).asc) + else + self + end + + relation.to_a[-index] + # TODO: can be made more performant on large result sets by + # for instance, last(index)[-index] (which would require + # refactoring the last(n) finder method to make test suite pass), + # or by using a combination of reverse_order, limit, and offset, + # e.g., reverse_order.offset(index-1).first + end + end + private def find_nth_with_limit_and_offset(index, limit, offset:) # :nodoc: |