Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 9235

Show
Ignore:
Timestamp:
04/06/08 22:26:15 (8 months ago)
Author:
pratik
Message:

Ensure that respond_to? considers dynamic finder methods. Closes #11538. [floehopper]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activerecord/CHANGELOG

    r9232 r9235  
    11*SVN* 
     2 
     3* Ensure that respond_to? considers dynamic finder methods. Closes #11538. [floehopper] 
    24 
    35* Ensure that save on parent object fails for invalid has_one association. Closes #10518. [Pratik] 
  • trunk/activerecord/lib/active_record/base.rb

    r9226 r9235  
    12641264      end 
    12651265 
     1266      def respond_to?(method_id, include_private = false) 
     1267        if match = matches_dynamic_finder?(method_id) || matches_dynamic_finder_with_initialize_or_create?(method_id) 
     1268          return true if all_attributes_exists?(extract_attribute_names_from_match(match)) 
     1269        end 
     1270        super 
     1271      end 
     1272 
    12661273      private 
    12671274        def find_initial(options) 
     
    15691576        # attempts to use it do not run through method_missing. 
    15701577        def method_missing(method_id, *arguments) 
    1571           if match = /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(method_id.to_s
     1578          if match = matches_dynamic_finder?(method_id
    15721579            finder = determine_finder(match) 
    15731580 
     
    15931600            }, __FILE__, __LINE__ 
    15941601            send(method_id, *arguments) 
    1595           elsif match = /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/.match(method_id.to_s
     1602          elsif match = matches_dynamic_finder_with_initialize_or_create?(method_id
    15961603            instantiator = determine_instantiator(match) 
    15971604            attribute_names = extract_attribute_names_from_match(match) 
     
    16291636            super 
    16301637          end 
     1638        end 
     1639 
     1640        def matches_dynamic_finder?(method_id) 
     1641          /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(method_id.to_s) 
     1642        end 
     1643 
     1644        def matches_dynamic_finder_with_initialize_or_create?(method_id) 
     1645          /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/.match(method_id.to_s) 
    16311646        end 
    16321647 
  • trunk/activerecord/test/cases/finder_test.rb

    r9090 r9235  
    417417  def test_find_by_one_attribute_caches_dynamic_finder 
    418418    # ensure this test can run independently of order 
    419     class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.respond_to?(:find_by_title) 
    420     assert !Topic.respond_to?(:find_by_title) 
     419    class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.public_methods.any? { |m| m.to_s == 'find_by_title' } 
     420    assert !Topic.public_methods.any? { |m| m.to_s == 'find_by_title' } 
    421421    t = Topic.find_by_title("The First Topic") 
    422     assert Topic.respond_to?(:find_by_title) 
     422    assert Topic.public_methods.any? { |m| m.to_s == 'find_by_title' } 
    423423  end 
    424424 
    425425  def test_dynamic_finder_returns_same_results_after_caching 
    426426    # ensure this test can run independently of order 
    427     class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.respond_to?(:find_by_title) 
     427    class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.public_method_defined?(:find_by_title) 
    428428    t = Topic.find_by_title("The First Topic") 
    429429    assert_equal t, Topic.find_by_title("The First Topic") # find_by_title has been cached 
     
    475475  def test_dynamic_finder_on_one_attribute_with_conditions_caches_method 
    476476    # ensure this test can run independently of order 
    477     class << Account; self; end.send(:remove_method, :find_by_credit_limit) if Account.respond_to?(:find_by_credit_limit) 
    478     assert !Account.respond_to?(:find_by_credit_limit) 
     477    class << Account; self; end.send(:remove_method, :find_by_credit_limit) if Account.public_methods.any? { |m| m.to_s == 'find_by_credit_limit' } 
     478    assert !Account.public_methods.any? { |m| m.to_s == 'find_by_credit_limit' } 
    479479    a = Account.find_by_credit_limit(50, :conditions => ['firm_id = ?', 6]) 
    480     assert Account.respond_to?(:find_by_credit_limit) 
     480    assert Account.public_methods.any? { |m| m.to_s == 'find_by_credit_limit' } 
    481481  end 
    482482 
    483483  def test_dynamic_finder_on_one_attribute_with_conditions_returns_same_results_after_caching 
    484484    # ensure this test can run independently of order 
    485     class << Account; self; end.send(:remove_method, :find_by_credit_limit) if Account.respond_to?(:find_by_credit_limit) 
     485    class << Account; self; end.send(:remove_method, :find_by_credit_limit) if Account.public_methods.any? { |m| m.to_s == 'find_by_credit_limit' } 
    486486    a = Account.find_by_credit_limit(50, :conditions => ['firm_id = ?', 6]) 
    487487    assert_equal a, Account.find_by_credit_limit(50, :conditions => ['firm_id = ?', 6]) # find_by_credit_limit has been cached 
     
    703703   
    704704  def test_dynamic_find_or_initialize_from_one_attribute_caches_method 
    705     class << Company; self; end.send(:remove_method, :find_or_initialize_by_name) if Company.respond_to?(:find_or_initialize_by_name) 
    706     assert !Company.respond_to?(:find_or_initialize_by_name) 
     705    class << Company; self; end.send(:remove_method, :find_or_initialize_by_name) if Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' } 
     706    assert !Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' } 
    707707    sig38 = Company.find_or_initialize_by_name("38signals") 
    708     assert Company.respond_to?(:find_or_initialize_by_name) 
     708    assert Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' } 
    709709  end 
    710710