Added ActiveRecord::Base.find(:last) (closes #11338) [miloops]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@9012 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
8cc28daad6
commit
d5a4d5abb4
@ -1,5 +1,7 @@
|
|||||||
*SVN*
|
*SVN*
|
||||||
|
|
||||||
|
* Added ActiveRecord::Base.find(:last) #11338 [miloops]
|
||||||
|
|
||||||
* test_native_types expects DateTime.local_offset instead of DateTime.now.offset; fixes test breakage due to dst transition [Geoff Buesing]
|
* test_native_types expects DateTime.local_offset instead of DateTime.now.offset; fixes test breakage due to dst transition [Geoff Buesing]
|
||||||
|
|
||||||
* Add :readonly option to HasManyThrough associations. #11156 [miloops]
|
* Add :readonly option to HasManyThrough associations. #11156 [miloops]
|
||||||
|
@ -430,12 +430,14 @@ def self.reset_subclasses #:nodoc:
|
|||||||
@@schema_format = :ruby
|
@@schema_format = :ruby
|
||||||
|
|
||||||
class << self # Class methods
|
class << self # Class methods
|
||||||
# Find operates with three different retrieval approaches:
|
# Find operates with four different retrieval approaches:
|
||||||
#
|
#
|
||||||
# * Find by id: This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
|
# * Find by id: This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
|
||||||
# If no record can be found for all of the listed ids, then RecordNotFound will be raised.
|
# If no record can be found for all of the listed ids, then RecordNotFound will be raised.
|
||||||
# * Find first: This will return the first record matched by the options used. These options can either be specific
|
# * Find first: This will return the first record matched by the options used. These options can either be specific
|
||||||
# conditions or merely an order. If no record can be matched, nil is returned.
|
# conditions or merely an order. If no record can be matched, nil is returned.
|
||||||
|
# * Find last: This will return the last record matched by the options used. These options can either be specific
|
||||||
|
# conditions or merely an order. If no record can be matched, nil is returned.
|
||||||
# * Find all: This will return all the records matched by the options used. If no records are found, an empty array is returned.
|
# * Find all: This will return all the records matched by the options used. If no records are found, an empty array is returned.
|
||||||
#
|
#
|
||||||
# All approaches accept an options hash as their last parameter. The options are:
|
# All approaches accept an options hash as their last parameter. The options are:
|
||||||
@ -475,6 +477,11 @@ class << self # Class methods
|
|||||||
# Person.find(:first, :conditions => [ "user_name = ?", user_name])
|
# Person.find(:first, :conditions => [ "user_name = ?", user_name])
|
||||||
# Person.find(:first, :order => "created_on DESC", :offset => 5)
|
# Person.find(:first, :order => "created_on DESC", :offset => 5)
|
||||||
#
|
#
|
||||||
|
# Examples for find last:
|
||||||
|
# Person.find(:last) # returns the last object fetched by SELECT * FROM people
|
||||||
|
# Person.find(:last, :conditions => [ "user_name = ?", user_name])
|
||||||
|
# Person.find(:last, :order => "created_on DESC", :offset => 5)
|
||||||
|
#
|
||||||
# Examples for find all:
|
# Examples for find all:
|
||||||
# Person.find(:all) # returns an array of objects for all the rows fetched by SELECT * FROM people
|
# Person.find(:all) # returns an array of objects for all the rows fetched by SELECT * FROM people
|
||||||
# Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
|
# Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
|
||||||
@ -499,6 +506,7 @@ def find(*args)
|
|||||||
|
|
||||||
case args.first
|
case args.first
|
||||||
when :first then find_initial(options)
|
when :first then find_initial(options)
|
||||||
|
when :last then find_last(options)
|
||||||
when :all then find_every(options)
|
when :all then find_every(options)
|
||||||
else find_from_ids(args, options)
|
else find_from_ids(args, options)
|
||||||
end
|
end
|
||||||
@ -1236,6 +1244,35 @@ def find_initial(options)
|
|||||||
find_every(options).first
|
find_every(options).first
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_last(options)
|
||||||
|
order = options[:order]
|
||||||
|
|
||||||
|
if order
|
||||||
|
order = reverse_sql_order(order)
|
||||||
|
elsif !scoped?(:find, :order)
|
||||||
|
order = "#{table_name}.#{primary_key} DESC"
|
||||||
|
end
|
||||||
|
|
||||||
|
if scoped?(:find, :order)
|
||||||
|
scoped_order = reverse_sql_order(scope(:find, :order))
|
||||||
|
scoped_methods.select { |s| s[:find].update(:order => scoped_order) }
|
||||||
|
end
|
||||||
|
|
||||||
|
find_initial(options.merge({ :order => order }))
|
||||||
|
end
|
||||||
|
|
||||||
|
def reverse_sql_order(order_query)
|
||||||
|
reversed_query = order_query.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')
|
||||||
|
elsif !s.match(/\s(asc|ASC|desc|DESC)$/)
|
||||||
|
s.concat(' DESC')
|
||||||
|
end
|
||||||
|
}.join(',')
|
||||||
|
end
|
||||||
|
|
||||||
def find_every(options)
|
def find_every(options)
|
||||||
include_associations = merge_includes(scope(:find, :include), options[:include])
|
include_associations = merge_includes(scope(:find, :include), options[:include])
|
||||||
|
|
||||||
|
@ -1616,6 +1616,33 @@ def test_scoped_find_order_including_has_many_association
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_find_last
|
||||||
|
last = Developer.find :last
|
||||||
|
assert_equal last, Developer.find(:first, :order => 'id desc')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_find_ordered_last
|
||||||
|
last = Developer.find :last, :order => 'developers.salary ASC'
|
||||||
|
assert_equal last, Developer.find(:all, :order => 'developers.salary ASC').last
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_find_reverse_ordered_last
|
||||||
|
last = Developer.find :last, :order => 'developers.salary DESC'
|
||||||
|
assert_equal last, Developer.find(:all, :order => 'developers.salary DESC').last
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_find_multiple_ordered_last
|
||||||
|
last = Developer.find :last, :order => 'developers.name, developers.salary DESC'
|
||||||
|
assert_equal last, Developer.find(:all, :order => 'developers.name, developers.salary DESC').last
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_find_scoped_ordered_last
|
||||||
|
last_developer = Developer.with_scope(:find => { :order => 'developers.salary ASC' }) do
|
||||||
|
Developer.find(:last)
|
||||||
|
end
|
||||||
|
assert_equal last_developer, Developer.find(:all, :order => 'developers.salary ASC').last
|
||||||
|
end
|
||||||
|
|
||||||
def test_abstract_class
|
def test_abstract_class
|
||||||
assert !ActiveRecord::Base.abstract_class?
|
assert !ActiveRecord::Base.abstract_class?
|
||||||
assert LoosePerson.abstract_class?
|
assert LoosePerson.abstract_class?
|
||||||
|
Loading…
Reference in New Issue
Block a user