mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Provide Association Extensions access to the instance that the association is being accessed from. Closes #4433 [josh@hasmanythrough.com]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4372 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
062845b4da
commit
ea51d72edb
5 changed files with 57 additions and 1 deletions
|
@ -1,5 +1,8 @@
|
||||||
*SVN*
|
*SVN*
|
||||||
|
|
||||||
|
* Provide Association Extensions access to the instance that the association is being accessed from.
|
||||||
|
Closes #4433 [josh@hasmanythrough.com]
|
||||||
|
|
||||||
* Update OpenBase adaterp's maintainer's email address. Closes #5176. [Derrick Spell]
|
* Update OpenBase adaterp's maintainer's email address. Closes #5176. [Derrick Spell]
|
||||||
|
|
||||||
* Add a quick note about :select and eagerly included associations. [Rick]
|
* Add a quick note about :select and eagerly included associations. [Rick]
|
||||||
|
|
|
@ -232,6 +232,13 @@ module ActiveRecord
|
||||||
# has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension]
|
# has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension]
|
||||||
# end
|
# 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:
|
||||||
|
#
|
||||||
|
# * +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 the collection of associated objects for has_many and has_and_belongs_to_many.
|
||||||
|
#
|
||||||
# === Association Join Models
|
# === Association Join Models
|
||||||
#
|
#
|
||||||
# Has Many associations can be configured with the :through option to use an explicit join model to retrieve the data. This
|
# Has Many associations can be configured with the :through option to use an explicit join model to retrieve the data. This
|
||||||
|
|
|
@ -4,7 +4,7 @@ module ActiveRecord
|
||||||
attr_reader :reflection
|
attr_reader :reflection
|
||||||
alias_method :proxy_respond_to?, :respond_to?
|
alias_method :proxy_respond_to?, :respond_to?
|
||||||
alias_method :proxy_extend, :extend
|
alias_method :proxy_extend, :extend
|
||||||
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?|^proxy_respond_to\?|^proxy_extend|^send)/ }
|
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_)/ }
|
||||||
|
|
||||||
def initialize(owner, reflection)
|
def initialize(owner, reflection)
|
||||||
@owner, @reflection = owner, reflection
|
@owner, @reflection = owner, reflection
|
||||||
|
@ -12,6 +12,18 @@ module ActiveRecord
|
||||||
reset
|
reset
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def proxy_owner
|
||||||
|
@owner
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxy_reflection
|
||||||
|
@reflection
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxy_target
|
||||||
|
@target
|
||||||
|
end
|
||||||
|
|
||||||
def respond_to?(symbol, include_priv = false)
|
def respond_to?(symbol, include_priv = false)
|
||||||
proxy_respond_to?(symbol, include_priv) || (load_target && @target.respond_to?(symbol, include_priv))
|
proxy_respond_to?(symbol, include_priv) || (load_target && @target.respond_to?(symbol, include_priv))
|
||||||
end
|
end
|
||||||
|
|
|
@ -65,6 +65,29 @@ class AssociationsTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class AssociationProxyTest < Test::Unit::TestCase
|
||||||
|
fixtures :authors, :posts
|
||||||
|
|
||||||
|
def test_proxy_accessors
|
||||||
|
welcome = posts(:welcome)
|
||||||
|
assert_equal welcome, welcome.author.proxy_owner
|
||||||
|
assert_equal welcome.class.reflect_on_association(:author), welcome.author.proxy_reflection
|
||||||
|
welcome.author.class # force load target
|
||||||
|
assert_equal welcome.author, welcome.author.proxy_target
|
||||||
|
|
||||||
|
david = authors(:david)
|
||||||
|
assert_equal david, david.posts.proxy_owner
|
||||||
|
assert_equal david.class.reflect_on_association(:posts), david.posts.proxy_reflection
|
||||||
|
david.posts.first # force load target
|
||||||
|
assert_equal david.posts, david.posts.proxy_target
|
||||||
|
|
||||||
|
assert_equal david, david.posts_with_extension.testing_proxy_owner
|
||||||
|
assert_equal david.class.reflect_on_association(:posts_with_extension), david.posts_with_extension.testing_proxy_reflection
|
||||||
|
david.posts_with_extension.first # force load target
|
||||||
|
assert_equal david.posts_with_extension, david.posts_with_extension.testing_proxy_target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class HasOneAssociationsTest < Test::Unit::TestCase
|
class HasOneAssociationsTest < Test::Unit::TestCase
|
||||||
fixtures :accounts, :companies, :developers, :projects, :developers_projects
|
fixtures :accounts, :companies, :developers, :projects, :developers_projects
|
||||||
|
|
||||||
|
|
11
activerecord/test/fixtures/author.rb
vendored
11
activerecord/test/fixtures/author.rb
vendored
|
@ -3,6 +3,17 @@ class Author < ActiveRecord::Base
|
||||||
has_many :posts_with_comments, :include => :comments, :class_name => "Post"
|
has_many :posts_with_comments, :include => :comments, :class_name => "Post"
|
||||||
has_many :posts_with_categories, :include => :categories, :class_name => "Post"
|
has_many :posts_with_categories, :include => :categories, :class_name => "Post"
|
||||||
has_many :posts_with_comments_and_categories, :include => [ :comments, :categories ], :order => "posts.id", :class_name => "Post"
|
has_many :posts_with_comments_and_categories, :include => [ :comments, :categories ], :order => "posts.id", :class_name => "Post"
|
||||||
|
has_many :posts_with_extension, :class_name => "Post" do #, :extend => ProxyTestExtension
|
||||||
|
def testing_proxy_owner
|
||||||
|
proxy_owner
|
||||||
|
end
|
||||||
|
def testing_proxy_reflection
|
||||||
|
proxy_reflection
|
||||||
|
end
|
||||||
|
def testing_proxy_target
|
||||||
|
proxy_target
|
||||||
|
end
|
||||||
|
end
|
||||||
has_many :comments, :through => :posts
|
has_many :comments, :through => :posts
|
||||||
has_many :funky_comments, :through => :posts, :source => :comments
|
has_many :funky_comments, :through => :posts, :source => :comments
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue