diff options
author | Marcelo Silveira <marcelo@mhfs.com.br> | 2012-04-26 21:03:25 -0300 |
---|---|---|
committer | Marcelo Silveira <marcelo@mhfs.com.br> | 2012-05-02 21:25:40 -0300 |
commit | 1379375f93c53d4c49fa8592b6117c3ade263f2e (patch) | |
tree | a39b16aa181cfd00b0ca253873f0dd1bcb7f29ff /activerecord | |
parent | 489166e114ba3af54b1f2081027cd44078d32bbc (diff) | |
download | rails-1379375f93c53d4c49fa8592b6117c3ade263f2e.tar.gz rails-1379375f93c53d4c49fa8592b6117c3ade263f2e.tar.bz2 rails-1379375f93c53d4c49fa8592b6117c3ade263f2e.zip |
Introducing `take` as a replacement to the old behavior of `first`
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/querying.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/finder_methods.rb | 27 | ||||
-rw-r--r-- | activerecord/test/cases/finder_test.rb | 26 |
3 files changed, 52 insertions, 3 deletions
diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb index 29b8b2fb73..4d8283bcff 100644 --- a/activerecord/lib/active_record/querying.rb +++ b/activerecord/lib/active_record/querying.rb @@ -3,7 +3,7 @@ require 'active_support/deprecation' module ActiveRecord module Querying - delegate :find, :first, :first!, :last, :last!, :all, :exists?, :any?, :many?, :to => :scoped + delegate :find, :take, :take!, :first, :first!, :last, :last!, :all, :exists?, :any?, :many?, :to => :scoped delegate :first_or_create, :first_or_create!, :first_or_initialize, :to => :scoped delegate :find_by, :find_by!, :to => :scoped delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, :to => :scoped diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 4a41f1ea8b..7af69d3483 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -60,6 +60,25 @@ module ActiveRecord where(*args).first! end + # Gives a record (or N records if a parameter is supplied) without any implied + # order. The order will depend on the database implementation. + # If an order is supplied it will be respected. + # + # Examples: + # + # Person.take # returns an object fetched by SELECT * FROM people + # Person.take(5) # returns 5 objects fetched by SELECT * FROM people LIMIT 5 + # Person.where(["name LIKE '%?'", name]).take + def take(limit = nil) + limit ? limit(limit).to_a : find_take + end + + # Same as +take+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record + # is found. Note that <tt>take!</tt> accepts no arguments. + def take! + take or raise RecordNotFound + end + # Find the first record (or first N records if a parameter is supplied). # If no order is defined it will order by primary key. # @@ -329,6 +348,14 @@ module ActiveRecord end end + def find_take + if loaded? + @records.take(1)[0] + else + @take ||= limit(1).to_a[0] + end + end + def find_first if loaded? @records.first diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index fdc7fad40a..54801bd101 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -143,6 +143,26 @@ class FinderTest < ActiveRecord::TestCase assert_equal [Account], accounts.collect(&:class).uniq end + def test_take + assert_equal topics(:first), Topic.take + end + + def test_take_failing + assert_nil Topic.where("title = 'This title does not exist'").take + end + + def test_take_bang_present + assert_nothing_raised do + assert_equal topics(:second), Topic.where("title = 'The Second Topic of the day'").take! + end + end + + def test_take_bang_missing + assert_raises ActiveRecord::RecordNotFound do + Topic.where("title = 'This title does not exist'").take! + end + end + def test_first assert_equal topics(:second).title, Topic.where("title = 'The Second Topic of the day'").first.title end @@ -197,7 +217,8 @@ class FinderTest < ActiveRecord::TestCase end end - def test_first_and_last_with_integer_should_use_sql_limit + def test_take_and_first_and_last_with_integer_should_use_sql_limit + assert_sql(/LIMIT 3|ROWNUM <= 3/) { Topic.take(3).entries } assert_sql(/LIMIT 2|ROWNUM <= 2/) { Topic.first(2).entries } assert_sql(/LIMIT 5|ROWNUM <= 5/) { Topic.last(5).entries } end @@ -218,7 +239,8 @@ class FinderTest < ActiveRecord::TestCase assert_no_match(/LIMIT/, query.first) end - def test_first_and_last_with_integer_should_return_an_array + def test_take_and_first_and_last_with_integer_should_return_an_array + assert_kind_of Array, Topic.take(5) assert_kind_of Array, Topic.first(5) assert_kind_of Array, Topic.last(5) end |