aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorCarlos Antonio da Silva <carlosantoniodasilva@gmail.com>2012-05-02 23:09:40 -0300
committerCarlos Antonio da Silva <carlosantoniodasilva@gmail.com>2012-05-02 23:23:35 -0300
commit5d26c8f00a11e40660be7516a13512ed522863ed (patch)
treeb8954479f19d5a9ad3fdb44d4f0d0f7ce11a5d54 /activerecord
parent36720af42995c8bac06ea7187e2c5768f89c2783 (diff)
downloadrails-5d26c8f00a11e40660be7516a13512ed522863ed.tar.gz
rails-5d26c8f00a11e40660be7516a13512ed522863ed.tar.bz2
rails-5d26c8f00a11e40660be7516a13512ed522863ed.zip
Fix issue with private kernel methods and collection associations. Closes #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.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb4
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb5
-rw-r--r--activerecord/test/models/company.rb5
3 files changed, 12 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index ad029d1101..50d16b16a9 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -81,7 +81,7 @@ module ActiveRecord
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 @@ module ActiveRecord
end
else
- scoped.readonly(nil).send(method, *args, &block)
+ scoped.readonly(nil).public_send(method, *args, &block)
end
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index a98e5b115c..f74fe42dc2 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -1703,4 +1703,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
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
diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb
index fbdfaa2c29..7b993d5a2c 100644
--- a/activerecord/test/models/company.rb
+++ b/activerecord/test/models/company.rb
@@ -198,6 +198,11 @@ class Account < ActiveRecord::Base
@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