aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb30
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb26
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb16
3 files changed, 59 insertions, 13 deletions
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 52531a3520..89b7945c78 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -96,11 +96,31 @@ module ActiveRecord
end
def first(*args)
- first_or_last(:first, *args)
+ first_nth_or_last(:first, *args)
+ end
+
+ def second(*args)
+ first_nth_or_last(:second, *args)
+ end
+
+ def third(*args)
+ first_nth_or_last(:third, *args)
+ end
+
+ def fourth(*args)
+ first_nth_or_last(:fourth, *args)
+ end
+
+ def fifth(*args)
+ first_nth_or_last(:fifth, *args)
+ end
+
+ def forty_two(*args)
+ first_nth_or_last(:forty_two, *args)
end
def last(*args)
- first_or_last(:last, *args)
+ first_nth_or_last(:last, *args)
end
def build(attributes = {}, &block)
@@ -526,7 +546,7 @@ module ActiveRecord
# * target already loaded
# * owner is new record
# * target contains new or changed record(s)
- def fetch_first_or_last_using_find?(args)
+ def fetch_first_nth_or_last_using_find?(args)
if args.first.is_a?(Hash)
true
else
@@ -564,10 +584,10 @@ module ActiveRecord
end
# Fetches the first/last using SQL if possible, otherwise from the target array.
- def first_or_last(type, *args)
+ def first_nth_or_last(type, *args)
args.shift if args.first.is_a?(Hash) && args.first.empty?
- collection = fetch_first_or_last_using_find?(args) ? scope : load_target
+ collection = fetch_first_nth_or_last_using_find?(args) ? scope : load_target
collection.send(type, *args).tap do |record|
set_inverse_instance record if record.is_a? ActiveRecord::Base
end
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 10434734e3..a67b834a80 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -170,6 +170,32 @@ module ActiveRecord
@association.first(*args)
end
+ # Same as +first+ except returns only the second record.
+ def second(*args)
+ @association.second(*args)
+ end
+
+ # Same as +first+ except returns only the third record.
+ def third(*args)
+ @association.third(*args)
+ end
+
+ # Same as +first+ except returns only the fourth record.
+ def fourth(*args)
+ @association.fourth(*args)
+ end
+
+ # Same as +first+ except returns only the fifth record.
+ def fifth(*args)
+ @association.fifth(*args)
+ end
+
+ # Same as +first+ except returns only the forty second record.
+ # Also known as accessing "the reddit".
+ def forty_two(*args)
+ @association.forty_two(*args)
+ end
+
# Returns the last record, or the last +n+ records, from the collection.
# If the collection is empty, the first form returns +nil+, and the second
# form returns an empty array.
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index f2ac351a8b..2dd1e6f14b 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -129,7 +129,7 @@ module ActiveRecord
if limit
find_nth_with_limit(offset_value, limit)
else
- find_nth(offset_value)
+ find_nth(:first, offset_value)
end
end
@@ -179,7 +179,7 @@ module ActiveRecord
# Person.offset(3).second # returns the second object from OFFSET 3 (which is OFFSET 4)
# Person.where(["user_name = :u", { u: user_name }]).second
def second
- find_nth(offset_value ? offset_value + 1 : 1)
+ find_nth(:second, offset_value ? offset_value + 1 : 1)
end
# Same as +second+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
@@ -195,7 +195,7 @@ module ActiveRecord
# Person.offset(3).third # returns the third object from OFFSET 3 (which is OFFSET 5)
# Person.where(["user_name = :u", { u: user_name }]).third
def third
- find_nth(offset_value ? offset_value + 2 : 2)
+ find_nth(:third, offset_value ? offset_value + 2 : 2)
end
# Same as +third+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
@@ -211,7 +211,7 @@ module ActiveRecord
# Person.offset(3).fourth # returns the fourth object from OFFSET 3 (which is OFFSET 6)
# Person.where(["user_name = :u", { u: user_name }]).fourth
def fourth
- find_nth(offset_value ? offset_value + 3 : 3)
+ find_nth(:fourth, offset_value ? offset_value + 3 : 3)
end
# Same as +fourth+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
@@ -227,7 +227,7 @@ module ActiveRecord
# Person.offset(3).fifth # returns the fifth object from OFFSET 3 (which is OFFSET 7)
# Person.where(["user_name = :u", { u: user_name }]).fifth
def fifth
- find_nth(offset_value ? offset_value + 4 : 4)
+ find_nth(:fifth, offset_value ? offset_value + 4 : 4)
end
# Same as +fifth+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
@@ -243,7 +243,7 @@ module ActiveRecord
# Person.offset(3).forty_two # returns the fifth object from OFFSET 3 (which is OFFSET 44)
# Person.where(["user_name = :u", { u: user_name }]).forty_two
def forty_two
- find_nth(offset_value ? offset_value + 41 : 41)
+ find_nth(:forty_two, offset_value ? offset_value + 41 : 41)
end
# Same as +forty_two+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
@@ -444,9 +444,9 @@ module ActiveRecord
end
end
- def find_nth(offset)
+ def find_nth(ordinal, offset)
if loaded?
- @records.first
+ @records.send(ordinal)
else
@offsets[offset] ||= find_nth_with_limit(offset, 1).first
end