aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Susser <josh@hasmanythrough.com>2008-08-25 21:28:53 -0700
committerJeremy Kemper <jeremy@bitsweat.net>2008-08-25 23:33:16 -0700
commit1092c181b5568d06e84f6a3253aaca81c02a2b2c (patch)
tree3fb246c856bbefddf8fc1e635eb765c540619c41
parent143f5fbb21b6dfcaab63d67b44afd922dab9dcf5 (diff)
downloadrails-1092c181b5568d06e84f6a3253aaca81c02a2b2c.tar.gz
rails-1092c181b5568d06e84f6a3253aaca81c02a2b2c.tar.bz2
rails-1092c181b5568d06e84f6a3253aaca81c02a2b2c.zip
add dynamic finder bang version to raise RecordNotFound
[#905 state:resolved] Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
-rw-r--r--activerecord/lib/active_record/base.rb4
-rw-r--r--activerecord/lib/active_record/dynamic_finder_match.rb7
-rw-r--r--activerecord/test/cases/finder_test.rb14
3 files changed, 24 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 523b619e62..5c30f80555 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1679,6 +1679,7 @@ module ActiveRecord #:nodoc:
super unless all_attributes_exists?(attribute_names)
if match.finder?
finder = match.finder
+ bang = match.bang?
self.class_eval %{
def self.#{method_id}(*args)
options = args.extract_options!
@@ -1687,13 +1688,14 @@ module ActiveRecord #:nodoc:
validate_find_options(options)
set_readonly_option!(options)
- if options[:conditions]
+ #{'result = ' if bang}if options[:conditions]
with_scope(:find => finder_options) do
ActiveSupport::Deprecation.silence { send(:#{finder}, options) }
end
else
ActiveSupport::Deprecation.silence { send(:#{finder}, options.merge(finder_options)) }
end
+ #{'result || raise(RecordNotFound)' if bang}
end
}, __FILE__, __LINE__
send(method_id, *arguments)
diff --git a/activerecord/lib/active_record/dynamic_finder_match.rb b/activerecord/lib/active_record/dynamic_finder_match.rb
index 4618e777a4..b105b919f5 100644
--- a/activerecord/lib/active_record/dynamic_finder_match.rb
+++ b/activerecord/lib/active_record/dynamic_finder_match.rb
@@ -11,6 +11,9 @@ module ActiveRecord
when /^find_(all_by|by)_([_a-zA-Z]\w*)$/
@finder = :find_every if $1 == 'all_by'
names = $2
+ when /^find_by_([_a-zA-Z]\w*)\!$/
+ @bang = true
+ names = $1
when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
@instantiator = $1 == 'initialize' ? :new : :create
names = $2
@@ -29,5 +32,9 @@ module ActiveRecord
def instantiator?
@finder == :find_initial && !@instantiator.nil?
end
+
+ def bang?
+ @bang
+ end
end
end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 875d56f6c1..2ce49ed76f 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -25,6 +25,15 @@ class DynamicFinderMatchTest < ActiveRecord::TestCase
assert_equal %w(age sex location), match.attribute_names
end
+ def find_by_bang
+ match = ActiveRecord::DynamicFinderMatch.match("find_by_age_and_sex_and_location!")
+ assert_not_nil match
+ assert match.finder?
+ assert match.bang?
+ assert_equal :find_initial, match.finder
+ assert_equal %w(age sex location), match.attribute_names
+ end
+
def test_find_all_by
match = ActiveRecord::DynamicFinderMatch.match("find_all_by_age_and_sex_and_location")
assert_not_nil match
@@ -482,6 +491,11 @@ class FinderTest < ActiveRecord::TestCase
assert_nil Topic.find_by_title("The First Topic!")
end
+ def test_find_by_one_attribute_bang
+ assert_equal topics(:first), Topic.find_by_title!("The First Topic")
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find_by_title!("The First Topic!") }
+ end
+
def test_find_by_one_attribute_caches_dynamic_finder
# ensure this test can run independently of order
class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.public_methods.any? { |m| m.to_s == 'find_by_title' }