From 1878da9af0dfa4cf5e77b1cadd04a460143d6fcc Mon Sep 17 00:00:00 2001 From: Dylan Stamat Date: Thu, 30 Apr 2009 21:26:55 +1200 Subject: [PATCH] Adds ability to pass in integer to first/last finders, which returns N number of objects --- activerecord/lib/active_record/base.rb | 35 +++++++++++++++++++++++++------ activerecord/test/cases/finder_test.rb | 12 +++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 97c36a6..d3b20a1 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -611,8 +611,8 @@ module ActiveRecord #:nodoc: set_readonly_option!(options) case args.first - when :first then find_initial(options) - when :last then find_last(options) + when :first then find_initial(args, options) + when :last then find_last(args, options) when :all then find_every(options) else find_from_ids(args, options) end @@ -620,12 +620,26 @@ module ActiveRecord #:nodoc: # A convenience wrapper for find(:first, *args). You can pass in all the # same arguments to this method as you can to find(:first). + # You can optionally specify the number of entries you would like returned. + # + # ==== Examples + # + # # find first + # Person.first # returns the first object fetched by SELECT * FROM people + # Person.first(3) # returns the first 3 objects def first(*args) find(:first, *args) end # A convenience wrapper for find(:last, *args). You can pass in all the # same arguments to this method as you can to find(:last). + # You can optionally specify the number of entries you would like returned. + # + # ==== Examples + # + # # find last + # Person.last # returns the last object fetched by SELECT * FROM people + # Person.last(3) # returns the last 3 objects def last(*args) find(:last, *args) end @@ -1509,12 +1523,19 @@ module ActiveRecord #:nodoc: end private - def find_initial(options) - options.update(:limit => 1) - find_every(options).first + def find_initial(args, options) + args.delete_at(0) + + if args.first + options.update(:limit => args.first) + find_every(options) + else + options.update(:limit => 1) + find_every(options).first + end end - def find_last(options) + def find_last(args, options) order = options[:order] if order @@ -1530,7 +1551,7 @@ module ActiveRecord #:nodoc: end begin - find_initial(options.merge({ :order => order })) + find_initial(args, options.merge({ :order => order })) ensure scope[:order] = original_scoped_order if original_scoped_order end diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 28eb311..18ecca2 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -235,6 +235,18 @@ class FinderTest < ActiveRecord::TestCase assert_nil Topic.first(:conditions => "title = 'The Second Topic of the day!'") end + def test_first_with_integer + assert_equal(3, Topic.first(3).size) + end + + def test_first_with_integer_and_conditions + assert_equal(3, Topic.first(3, :conditions => "title like '%Topic%'").size) + end + + def test_first_with_integer_and_conditions_failing + assert_equal([], Topic.first(3, :conditions => "title like '%Topic!%'")) + end + def test_unexisting_record_exception_handling assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1).parent -- 1.6.0.4