public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
add dynamic finder bang version to raise RecordNotFound

[#905 state:resolved]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
joshsusser (author)
Mon Aug 25 21:28:53 -0700 2008
jeremy (committer)
Mon Aug 25 23:33:16 -0700 2008
commit  1092c181b5568d06e84f6a3253aaca81c02a2b2c
tree    3fb246c856bbefddf8fc1e635eb765c540619c41
parent  143f5fbb21b6dfcaab63d67b44afd922dab9dcf5
...
1679
1680
1681
 
1682
1683
1684
...
1687
1688
1689
1690
 
1691
1692
1693
1694
1695
1696
 
1697
1698
1699
...
1679
1680
1681
1682
1683
1684
1685
...
1688
1689
1690
 
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
0
@@ -1679,6 +1679,7 @@ module ActiveRecord #:nodoc:
0
             super unless all_attributes_exists?(attribute_names)
0
             if match.finder?
0
               finder = match.finder
0
+              bang = match.bang?
0
               self.class_eval %{
0
                 def self.#{method_id}(*args)
0
                   options = args.extract_options!
0
@@ -1687,13 +1688,14 @@ module ActiveRecord #:nodoc:
0
                   validate_find_options(options)
0
                   set_readonly_option!(options)
0
 
0
-                  if options[:conditions]
0
+                  #{'result = ' if bang}if options[:conditions]
0
                     with_scope(:find => finder_options) do
0
                       ActiveSupport::Deprecation.silence { send(:#{finder}, options) }
0
                     end
0
                   else
0
                     ActiveSupport::Deprecation.silence { send(:#{finder}, options.merge(finder_options)) }
0
                   end
0
+                  #{'result || raise(RecordNotFound)' if bang}
0
                 end
0
               }, __FILE__, __LINE__
0
               send(method_id, *arguments)
...
11
12
13
 
 
 
14
15
16
...
29
30
31
 
 
 
 
32
33
...
11
12
13
14
15
16
17
18
19
...
32
33
34
35
36
37
38
39
40
0
@@ -11,6 +11,9 @@ module ActiveRecord
0
       when /^find_(all_by|by)_([_a-zA-Z]\w*)$/
0
         @finder = :find_every if $1 == 'all_by'
0
         names = $2
0
+      when /^find_by_([_a-zA-Z]\w*)\!$/
0
+        @bang = true
0
+        names = $1
0
       when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
0
         @instantiator = $1 == 'initialize' ? :new : :create
0
         names = $2
0
@@ -29,5 +32,9 @@ module ActiveRecord
0
     def instantiator?
0
       @finder == :find_initial && !@instantiator.nil?
0
     end
0
+
0
+    def bang?
0
+      @bang
0
+    end
0
   end
0
 end
...
25
26
27
 
 
 
 
 
 
 
 
 
28
29
30
...
482
483
484
 
 
 
 
 
485
486
487
...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
491
492
493
494
495
496
497
498
499
500
501
0
@@ -25,6 +25,15 @@ class DynamicFinderMatchTest < ActiveRecord::TestCase
0
     assert_equal %w(age sex location), match.attribute_names
0
   end
0
 
0
+  def find_by_bang
0
+    match = ActiveRecord::DynamicFinderMatch.match("find_by_age_and_sex_and_location!")
0
+    assert_not_nil match
0
+    assert match.finder?
0
+    assert match.bang?
0
+    assert_equal :find_initial, match.finder
0
+    assert_equal %w(age sex location), match.attribute_names
0
+  end
0
+
0
   def test_find_all_by
0
     match = ActiveRecord::DynamicFinderMatch.match("find_all_by_age_and_sex_and_location")
0
     assert_not_nil match
0
@@ -482,6 +491,11 @@ class FinderTest < ActiveRecord::TestCase
0
     assert_nil Topic.find_by_title("The First Topic!")
0
   end
0
 
0
+  def test_find_by_one_attribute_bang
0
+    assert_equal topics(:first), Topic.find_by_title!("The First Topic")
0
+    assert_raises(ActiveRecord::RecordNotFound) { Topic.find_by_title!("The First Topic!") }
0
+  end
0
+
0
   def test_find_by_one_attribute_caches_dynamic_finder
0
     # ensure this test can run independently of order
0
     class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.public_methods.any? { |m| m.to_s == 'find_by_title' }

Comments

yaroslav Tue Aug 26 01:05:40 -0700 2008

This is awesome. Cheers!

benpickles Tue Aug 26 01:52:50 -0700 2008

yey!

trevorturk Tue Aug 26 07:19:20 -0700 2008

Sweet! I just wanted this yesterday.

anildigital Tue Aug 26 11:54:40 -0700 2008

Sweet