提交 24f0a872 编写于 作者: J Jon Leighton

Add a proxy_association method to association proxies, which can be called by...

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.
上级 46b82618
......@@ -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)
......
......@@ -460,6 +460,12 @@ def association_instance_set(name, association)
# * <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
......
......@@ -58,23 +58,27 @@ def initialize(association)
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 @@ def to_ary
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 @@ def clear
end
def reload
@association.reload
proxy_association.reload
self
end
end
......
......@@ -203,6 +203,11 @@ def test_reload_returns_assocition
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册