Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 9012

Show
Ignore:
Timestamp:
03/12/08 21:26:02 (2 months ago)
Author:
david
Message:

Added ActiveRecord::Base.find(:last) (closes #11338) [miloops]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activerecord/CHANGELOG

    r9003 r9012  
    11*SVN* 
     2 
     3* Added ActiveRecord::Base.find(:last) #11338 [miloops] 
    24 
    35* test_native_types expects DateTime.local_offset instead of DateTime.now.offset; fixes test breakage due to dst transition [Geoff Buesing] 
  • trunk/activerecord/lib/active_record/base.rb

    r9011 r9012  
    431431 
    432432    class << self # Class methods 
    433       # Find operates with three different retrieval approaches: 
     433      # Find operates with four different retrieval approaches: 
    434434      # 
    435435      # * 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]). 
    436436      #   If no record can be found for all of the listed ids, then RecordNotFound will be raised. 
    437437      # * Find first: This will return the first record matched by the options used. These options can either be specific 
     438      #   conditions or merely an order. If no record can be matched, nil is returned. 
     439      # * Find last: This will return the last record matched by the options used. These options can either be specific 
    438440      #   conditions or merely an order. If no record can be matched, nil is returned. 
    439441      # * Find all: This will return all the records matched by the options used. If no records are found, an empty array is returned. 
     
    476478      #   Person.find(:first, :order => "created_on DESC", :offset => 5) 
    477479      # 
     480      # Examples for find last: 
     481      #   Person.find(:last) # returns the last object fetched by SELECT * FROM people 
     482      #   Person.find(:last, :conditions => [ "user_name = ?", user_name]) 
     483      #   Person.find(:last, :order => "created_on DESC", :offset => 5) 
     484      # 
    478485      # Examples for find all: 
    479486      #   Person.find(:all) # returns an array of objects for all the rows fetched by SELECT * FROM people 
     
    500507        case args.first 
    501508          when :first then find_initial(options) 
     509          when :last  then find_last(options) 
    502510          when :all   then find_every(options) 
    503511          else             find_from_ids(args, options) 
     
    12371245        end 
    12381246 
     1247        def find_last(options) 
     1248          order = options[:order] 
     1249 
     1250          if order 
     1251            order = reverse_sql_order(order) 
     1252          elsif !scoped?(:find, :order) 
     1253            order = "#{table_name}.#{primary_key} DESC" 
     1254          end 
     1255 
     1256          if scoped?(:find, :order) 
     1257            scoped_order = reverse_sql_order(scope(:find, :order)) 
     1258            scoped_methods.select { |s| s[:find].update(:order => scoped_order) } 
     1259          end 
     1260           
     1261          find_initial(options.merge({ :order => order })) 
     1262        end 
     1263 
     1264        def reverse_sql_order(order_query) 
     1265          reversed_query = order_query.split(/,/).each { |s| 
     1266            if s.match(/\s(asc|ASC)$/) 
     1267              s.gsub!(/\s(asc|ASC)$/, ' DESC') 
     1268            elsif s.match(/\s(desc|DESC)$/) 
     1269              s.gsub!(/\s(desc|DESC)$/, ' ASC') 
     1270            elsif !s.match(/\s(asc|ASC|desc|DESC)$/)  
     1271              s.concat(' DESC') 
     1272            end 
     1273          }.join(',') 
     1274        end 
     1275         
    12391276        def find_every(options) 
    12401277          include_associations = merge_includes(scope(:find, :include), options[:include]) 
  • trunk/activerecord/test/cases/base_test.rb

    r8913 r9012  
    16171617  end 
    16181618 
     1619  def test_find_last 
     1620    last  = Developer.find :last 
     1621    assert_equal last, Developer.find(:first, :order => 'id desc') 
     1622  end 
     1623   
     1624  def test_find_ordered_last 
     1625    last  = Developer.find :last, :order => 'developers.salary ASC' 
     1626    assert_equal last, Developer.find(:all, :order => 'developers.salary ASC').last 
     1627  end 
     1628 
     1629  def test_find_reverse_ordered_last 
     1630    last  = Developer.find :last, :order => 'developers.salary DESC' 
     1631    assert_equal last, Developer.find(:all, :order => 'developers.salary DESC').last 
     1632  end 
     1633 
     1634  def test_find_multiple_ordered_last 
     1635    last  = Developer.find :last, :order => 'developers.name, developers.salary DESC' 
     1636    assert_equal last, Developer.find(:all, :order => 'developers.name, developers.salary DESC').last 
     1637  end 
     1638   
     1639  def test_find_scoped_ordered_last 
     1640    last_developer = Developer.with_scope(:find => { :order => 'developers.salary ASC' }) do 
     1641      Developer.find(:last) 
     1642    end 
     1643    assert_equal last_developer, Developer.find(:all, :order => 'developers.salary ASC').last 
     1644  end 
     1645   
    16191646  def test_abstract_class 
    16201647    assert !ActiveRecord::Base.abstract_class?