From d5e98dc859e24e9ebf8206a7955c6ac40819a117 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sun, 27 Dec 2009 19:04:30 +0530 Subject: Add relation.last and relation.reverse_order --- activerecord/lib/active_record/relation.rb | 35 +++++++++++++++++++++++++++++- activerecord/test/cases/relations_test.rb | 6 +++++ 2 files changed, 40 insertions(+), 1 deletion(-) 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 -- cgit v1.2.3