Permalink
Browse files

Add relation.last and relation.reverse_order

  • Loading branch information...
lifo committed Dec 27, 2009
1 parent 8957f5d commit d5e98dc859e24e9ebf8206a7955c6ac40819a117
Showing with 40 additions and 1 deletion.
  1. +34 −1 activerecord/lib/active_record/relation.rb
  2. +6 −0 activerecord/test/cases/relations_test.rb
@@ -44,6 +44,18 @@ def order(orders)
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 @@ def first
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 @@ def create_new_relation(relation = @relation, readonly = @readonly, preload = @a
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
@@ -309,4 +309,10 @@ def test_exists
assert ! fake.exists?
assert ! fake.exists?(authors(:david).id)
end
+
+ def test_last
+ authors = Author.scoped
+ assert_equal authors(:mary), authors.last
+ end
+
end

0 comments on commit d5e98dc

Please sign in to comment.