Permalink
Browse files

Implement proxy_owner, proxy_target and proxy_reflection methods on C…

…ollectionProxy with deprecations. Fixes #1148.
  • Loading branch information...
1 parent c037499 commit 0afd5850f5bba4bd3f1218e27a4a1488c9fdb83e @jonleighton jonleighton committed May 19, 2011
@@ -457,12 +457,13 @@ def association_instance_set(name, association)
# has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension]
# end
#
- # Some extensions can only be made to work with knowledge of the association proxy's internals.
- # Extensions can access relevant state using accessors on the association proxy:
+ # Some extensions can only be made to work with knowledge of the association's internals.
+ # Extensions can access relevant state using the following methods (where 'items' is the
+ # name of the association):
#
- # * +proxy_owner+ - Returns the object the association is part of.
- # * +proxy_reflection+ - Returns the reflection object that describes the association.
- # * +proxy_target+ - Returns the associated object for +belongs_to+ and +has_one+, or
+ # * +record.association(:items).owner+ - Returns the object the association is part of.
+ # * +record.association(:items).reflection+ - Returns the reflection object that describes the association.
+ # * +record.association(:items).target+ - 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+.
#
# === Association Join Models
@@ -123,6 +123,30 @@ def new(*args, &block)
method_missing(:new, *args, &block)
end
end
+
+ def proxy_owner
+ ActiveSupport::Deprecation.warn(
+ "Calling record.#{@association.reflection.name}.proxy_owner is deprecated. Please use " \
+ "record.association(:#{@association.reflection.name}).owner instead."
+ )
+ @association.owner
+ end
+
+ def proxy_target
+ ActiveSupport::Deprecation.warn(
+ "Calling record.#{@association.reflection.name}.proxy_target is deprecated. Please use " \
+ "record.association(:#{@association.reflection.name}).target instead."
+ )
+ @association.target
+ end
+
+ def proxy_reflection
+ ActiveSupport::Deprecation.warn(
+ "Calling record.#{@association.reflection.name}.proxy_reflection is deprecated. Please use " \
+ "record.association(:#{@association.reflection.name}).reflection instead."
+ )
+ @association.reflection
+ end
end
end
end
@@ -203,6 +203,18 @@ def test_reload_returns_assocition
assert_equal david.projects, david.projects.reload.reload
end
end
+
+ # Tests that proxy_owner, proxy_target and proxy_reflection are implement as deprecated methods
+ def test_proxy_deprecations
+ david = developers(:david)
+ david.projects.load_target
+
+ [:owner, :target, :reflection].each do |name|
+ assert_deprecated do
+ assert_equal david.association(:projects).send(name), david.projects.send("proxy_#{name}")
+ end
+ end
+ end
end
class OverridingAssociationsTest < ActiveRecord::TestCase

5 comments on commit 0afd585

@huerlisi

Log got filled up with hundreds of these deprecation warnings. Reading this commit I can't see any reason for this change at all? Probably my bad, but I just don't get it.

I'm using a module to enhance my associations and don't now how/why I should figure out the name of the association it's used in.

Using @association.owner now like read here: http://mileszs.posterous.com/deprecation-warnings-for-proxyowner-in-rails. Gives me a bad feeling as I'm now relying on a more internal thing, though...

Any hints about the motivation would be highly appreciated.

@jonleighton
Member

Hiya,

The code for managing associations has been split out from the actual proxy object. It would be bad to have lots of methods prefixed proxy_ which delegate to the association object - it is better to have people access the association object directly if they need to.

That's why I deprecated these methods.

However, since then, somebody has pointed out that it is hard to access the association object from within an extension module. So in the 3-1-stable branch, there is a proxy_association method, which allows you to call proxy_association.owner etc. This will be available in the next RC.

Accessing @association is bad advice as it's not a public API and may break in the future.

Jon

@huerlisi

Ah! Perfect, thanks a lot for the information!

Updating the deprecation methods with info about proxy_association might help others, too:-)

@jonleighton
Member

I did, see latest 3-1-stable branch.

@huerlisi

Damn, should do proper checks before ranting:-)

Good work, thanks a lot!

Please sign in to comment.