aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-07-27 12:36:00 +0100
committerXavier Noria <fxn@hashref.com>2011-08-13 16:22:20 -0700
commit05f1a9bcc3c9223768187e2379b508638dfa19b6 (patch)
treeeba4563b6fafd6ece21d1ed4eb55ab3ef3bc6a4b
parent924975a34aa3337cdf7a68f76bcae205815778f1 (diff)
downloadrails-05f1a9bcc3c9223768187e2379b508638dfa19b6.tar.gz
rails-05f1a9bcc3c9223768187e2379b508638dfa19b6.tar.bz2
rails-05f1a9bcc3c9223768187e2379b508638dfa19b6.zip
Add a proxy_association method to association proxies, which can be called by association extensions to access information about the association. This replaces proxy_owner etc with proxy_association.owner.
-rw-r--r--activerecord/CHANGELOG6
-rw-r--r--activerecord/lib/active_record/associations.rb6
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb16
-rw-r--r--activerecord/test/cases/associations_test.rb5
4 files changed, 27 insertions, 6 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index e448609cf4..e8d4b9c04e 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -24,6 +24,12 @@ a URI that specifies the connection configuration. For example:
*Rails 3.1.0 (unreleased)*
+* Add a proxy_association method to association proxies, which can be called by association
+ extensions to access information about the association. This replaces proxy_owner etc with
+ proxy_association.owner.
+
+ [Jon Leighton]
+
* ActiveRecord::MacroReflection::AssociationReflection#build_record has a new method signature.
Before: def build_association(*options)
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 029d7a9b15..2605a54cb6 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -460,6 +460,12 @@ module ActiveRecord
# * <tt>record.association(:items).target</tt> - Returns the associated object for +belongs_to+ and +has_one+, or
# the collection of associated objects for +has_many+ and +has_and_belongs_to_many+.
#
+ # However, inside the actual extension code, you will not have access to the <tt>record</tt> as
+ # above. In this case, you can access <tt>proxy_association</tt>. For example,
+ # <tt>record.association(:items)</tt> and <tt>record.items.proxy_association</tt> will return
+ # the same object, allowing you to make calls like <tt>proxy_association.owner</tt> inside
+ # association extensions.
+ #
# === Association Join Models
#
# Has Many associations can be configured with the <tt>:through</tt> option to use an
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 827dfb7ccb..6ba3d45aff 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -58,23 +58,27 @@ module ActiveRecord
alias_method :new, :build
+ def proxy_association
+ @association
+ end
+
def respond_to?(name, include_private = false)
super ||
(load_target && target.respond_to?(name, include_private)) ||
- @association.klass.respond_to?(name, include_private)
+ proxy_association.klass.respond_to?(name, include_private)
end
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|
- @association.send :set_owner_attributes, r
- @association.send :add_to_target, r
+ proxy_association.send :set_owner_attributes, r
+ proxy_association.send :add_to_target, r
yield(r) if block_given?
end
end
- if target.respond_to?(method) || (!@association.klass.respond_to?(method) && Class.respond_to?(method))
+ if target.respond_to?(method) || (!proxy_association.klass.respond_to?(method) && Class.respond_to?(method))
if load_target
if target.respond_to?(method)
target.send(method, *args, &block)
@@ -104,7 +108,7 @@ module ActiveRecord
alias_method :to_a, :to_ary
def <<(*records)
- @association.concat(records) && self
+ proxy_association.concat(records) && self
end
alias_method :push, :<<
@@ -114,7 +118,7 @@ module ActiveRecord
end
def reload
- @association.reload
+ proxy_association.reload
self
end
end
diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb
index 49d82ba2df..ffe2993e0f 100644
--- a/activerecord/test/cases/associations_test.rb
+++ b/activerecord/test/cases/associations_test.rb
@@ -203,6 +203,11 @@ class AssociationProxyTest < ActiveRecord::TestCase
assert_equal david.projects, david.projects.reload.reload
end
end
+
+ def test_proxy_association_accessor
+ david = developers(:david)
+ assert_equal david.association(:projects), david.projects.proxy_association
+ end
end
class OverridingAssociationsTest < ActiveRecord::TestCase