Permalink
Browse files

Fix issue with private kernel methods and collection associations. Cl…

…oses #2508

Change CollectionProxy#method_missing to use scoped.public_send, to
avoid a problem described in issue #2508 when trying to use class
methods with names like "open", that clash with private kernel methods.
Also changed the dynamic matcher instantiator to send straight to
scoped, to avoid another roundtrip to method_missing.
  • Loading branch information...
1 parent 36720af commit 5d26c8f00a11e40660be7516a13512ed522863ed @carlosantoniodasilva carlosantoniodasilva committed May 3, 2012
@@ -81,7 +81,7 @@ def respond_to?(name, include_private = false)
def method_missing(method, *args, &block)
match = DynamicFinderMatch.match(method)
if match && match.instantiator?
- send(:find_or_instantiator_by_attributes, match, match.attribute_names, *args) do |r|
+ scoped.send(:find_or_instantiator_by_attributes, match, match.attribute_names, *args) do |r|
proxy_association.send :set_owner_attributes, r
proxy_association.send :add_to_target, r
yield(r) if block_given?
@@ -101,7 +101,7 @@ def method_missing(method, *args, &block)
end
else
- scoped.readonly(nil).send(method, *args, &block)
+ scoped.readonly(nil).public_send(method, *args, &block)
end
end
@@ -1703,4 +1703,9 @@ def test_building_has_many_association_with_restrict_dependency
ensure
ActiveRecord::Base.dependent_restrict_raises = option_before
end
+
+ def test_collection_association_with_private_kernel_method
+ firm = companies(:first_firm)
+ assert_equal [accounts(:signals37)], firm.accounts.open
+ end
end
@@ -198,6 +198,11 @@ def self.destroyed_account_ids
@destroyed_account_ids ||= Hash.new { |h,k| h[k] = [] }
end
+ # Test private kernel method through collection proxy using has_many.
+ def self.open
+ where('firm_name = ?', '37signals')
+ end
+
before_destroy do |account|
if account.firm
Account.destroyed_account_ids[account.firm.id] << account.id

0 comments on commit 5d26c8f

Please sign in to comment.