mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
add dynamic finder bang version to raise RecordNotFound
[#905 state:resolved] Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
This commit is contained in:
parent
143f5fbb21
commit
1092c181b5
3 changed files with 24 additions and 1 deletions
|
@ -1679,6 +1679,7 @@ module ActiveRecord #:nodoc:
|
||||||
super unless all_attributes_exists?(attribute_names)
|
super unless all_attributes_exists?(attribute_names)
|
||||||
if match.finder?
|
if match.finder?
|
||||||
finder = match.finder
|
finder = match.finder
|
||||||
|
bang = match.bang?
|
||||||
self.class_eval %{
|
self.class_eval %{
|
||||||
def self.#{method_id}(*args)
|
def self.#{method_id}(*args)
|
||||||
options = args.extract_options!
|
options = args.extract_options!
|
||||||
|
@ -1687,13 +1688,14 @@ module ActiveRecord #:nodoc:
|
||||||
validate_find_options(options)
|
validate_find_options(options)
|
||||||
set_readonly_option!(options)
|
set_readonly_option!(options)
|
||||||
|
|
||||||
if options[:conditions]
|
#{'result = ' if bang}if options[:conditions]
|
||||||
with_scope(:find => finder_options) do
|
with_scope(:find => finder_options) do
|
||||||
ActiveSupport::Deprecation.silence { send(:#{finder}, options) }
|
ActiveSupport::Deprecation.silence { send(:#{finder}, options) }
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
ActiveSupport::Deprecation.silence { send(:#{finder}, options.merge(finder_options)) }
|
ActiveSupport::Deprecation.silence { send(:#{finder}, options.merge(finder_options)) }
|
||||||
end
|
end
|
||||||
|
#{'result || raise(RecordNotFound)' if bang}
|
||||||
end
|
end
|
||||||
}, __FILE__, __LINE__
|
}, __FILE__, __LINE__
|
||||||
send(method_id, *arguments)
|
send(method_id, *arguments)
|
||||||
|
|
|
@ -11,6 +11,9 @@ module ActiveRecord
|
||||||
when /^find_(all_by|by)_([_a-zA-Z]\w*)$/
|
when /^find_(all_by|by)_([_a-zA-Z]\w*)$/
|
||||||
@finder = :find_every if $1 == 'all_by'
|
@finder = :find_every if $1 == 'all_by'
|
||||||
names = $2
|
names = $2
|
||||||
|
when /^find_by_([_a-zA-Z]\w*)\!$/
|
||||||
|
@bang = true
|
||||||
|
names = $1
|
||||||
when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
|
when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
|
||||||
@instantiator = $1 == 'initialize' ? :new : :create
|
@instantiator = $1 == 'initialize' ? :new : :create
|
||||||
names = $2
|
names = $2
|
||||||
|
@ -29,5 +32,9 @@ module ActiveRecord
|
||||||
def instantiator?
|
def instantiator?
|
||||||
@finder == :find_initial && !@instantiator.nil?
|
@finder == :find_initial && !@instantiator.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bang?
|
||||||
|
@bang
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,6 +25,15 @@ class DynamicFinderMatchTest < ActiveRecord::TestCase
|
||||||
assert_equal %w(age sex location), match.attribute_names
|
assert_equal %w(age sex location), match.attribute_names
|
||||||
end
|
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
|
def test_find_all_by
|
||||||
match = ActiveRecord::DynamicFinderMatch.match("find_all_by_age_and_sex_and_location")
|
match = ActiveRecord::DynamicFinderMatch.match("find_all_by_age_and_sex_and_location")
|
||||||
assert_not_nil match
|
assert_not_nil match
|
||||||
|
@ -482,6 +491,11 @@ class FinderTest < ActiveRecord::TestCase
|
||||||
assert_nil Topic.find_by_title("The First Topic!")
|
assert_nil Topic.find_by_title("The First Topic!")
|
||||||
end
|
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
|
def test_find_by_one_attribute_caches_dynamic_finder
|
||||||
# ensure this test can run independently of order
|
# 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' }
|
class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.public_methods.any? { |m| m.to_s == 'find_by_title' }
|
||||||
|
|
Loading…
Reference in a new issue