aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/relation.rb35
-rw-r--r--activerecord/test/cases/relations_test.rb6
2 files changed, 40 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 4ca6871d0f..e52c7c3dc6 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -44,6 +44,18 @@ module ActiveRecord
create_new_relation(@relation.order(orders))
end
+ def reverse_order
+ relation = create_new_relation
+ relation.instance_variable_set(:@orders, nil)
+
+ order_clause = @relation.send(:order_clauses).join(', ')
+ if order_clause.present?
+ relation.order(reverse_sql_order(order_clause))
+ else
+ relation.order("#{@klass.table_name}.#{@klass.primary_key} DESC")
+ end
+ end
+
def limit(limits)
create_new_relation(@relation.take(limits))
end
@@ -153,13 +165,21 @@ module ActiveRecord
end
end
+ def last
+ if loaded?
+ @records.last
+ else
+ @last ||= reverse_order.limit(1).to_a[0]
+ end
+ end
+
def loaded?
@loaded
end
def reload
@loaded = false
- @records = @first = nil
+ @records = @first = @last = nil
self
end
@@ -265,5 +285,18 @@ module ActiveRecord
def where_clause(join_string = "\n\tAND ")
@relation.send(:where_clauses).join(join_string)
end
+
+ def reverse_sql_order(order_query)
+ order_query.to_s.split(/,/).each { |s|
+ if s.match(/\s(asc|ASC)$/)
+ s.gsub!(/\s(asc|ASC)$/, ' DESC')
+ elsif s.match(/\s(desc|DESC)$/)
+ s.gsub!(/\s(desc|DESC)$/, ' ASC')
+ else
+ s.concat(' DESC')
+ end
+ }.join(',')
+ end
+
end
end
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index d65fb5095c..37bd755a5c 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -309,4 +309,10 @@ class RelationTest < ActiveRecord::TestCase
assert ! fake.exists?
assert ! fake.exists?(authors(:david).id)
end
+
+ def test_last
+ authors = Author.scoped
+ assert_equal authors(:mary), authors.last
+ end
+
end