mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
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.
This commit is contained in:
parent
46b8261830
commit
24f0a872e6
4 changed files with 27 additions and 6 deletions
|
@ -24,6 +24,12 @@ a URI that specifies the connection configuration. For example:
|
||||||
|
|
||||||
*Rails 3.1.0 (unreleased)*
|
*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.
|
* ActiveRecord::MacroReflection::AssociationReflection#build_record has a new method signature.
|
||||||
|
|
||||||
Before: def build_association(*options)
|
Before: def build_association(*options)
|
||||||
|
|
|
@ -460,6 +460,12 @@ module ActiveRecord
|
||||||
# * <tt>record.association(:items).target</tt> - Returns the associated object for +belongs_to+ and +has_one+, or
|
# * <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+.
|
# 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
|
# === Association Join Models
|
||||||
#
|
#
|
||||||
# Has Many associations can be configured with the <tt>:through</tt> option to use an
|
# Has Many associations can be configured with the <tt>:through</tt> option to use an
|
||||||
|
|
|
@ -58,23 +58,27 @@ module ActiveRecord
|
||||||
|
|
||||||
alias_method :new, :build
|
alias_method :new, :build
|
||||||
|
|
||||||
|
def proxy_association
|
||||||
|
@association
|
||||||
|
end
|
||||||
|
|
||||||
def respond_to?(name, include_private = false)
|
def respond_to?(name, include_private = false)
|
||||||
super ||
|
super ||
|
||||||
(load_target && target.respond_to?(name, include_private)) ||
|
(load_target && target.respond_to?(name, include_private)) ||
|
||||||
@association.klass.respond_to?(name, include_private)
|
proxy_association.klass.respond_to?(name, include_private)
|
||||||
end
|
end
|
||||||
|
|
||||||
def method_missing(method, *args, &block)
|
def method_missing(method, *args, &block)
|
||||||
match = DynamicFinderMatch.match(method)
|
match = DynamicFinderMatch.match(method)
|
||||||
if match && match.instantiator?
|
if match && match.instantiator?
|
||||||
send(:find_or_instantiator_by_attributes, match, match.attribute_names, *args) do |r|
|
send(:find_or_instantiator_by_attributes, match, match.attribute_names, *args) do |r|
|
||||||
@association.send :set_owner_attributes, r
|
proxy_association.send :set_owner_attributes, r
|
||||||
@association.send :add_to_target, r
|
proxy_association.send :add_to_target, r
|
||||||
yield(r) if block_given?
|
yield(r) if block_given?
|
||||||
end
|
end
|
||||||
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 load_target
|
||||||
if target.respond_to?(method)
|
if target.respond_to?(method)
|
||||||
target.send(method, *args, &block)
|
target.send(method, *args, &block)
|
||||||
|
@ -104,7 +108,7 @@ module ActiveRecord
|
||||||
alias_method :to_a, :to_ary
|
alias_method :to_a, :to_ary
|
||||||
|
|
||||||
def <<(*records)
|
def <<(*records)
|
||||||
@association.concat(records) && self
|
proxy_association.concat(records) && self
|
||||||
end
|
end
|
||||||
alias_method :push, :<<
|
alias_method :push, :<<
|
||||||
|
|
||||||
|
@ -114,7 +118,7 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def reload
|
def reload
|
||||||
@association.reload
|
proxy_association.reload
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -203,6 +203,11 @@ class AssociationProxyTest < ActiveRecord::TestCase
|
||||||
assert_equal david.projects, david.projects.reload.reload
|
assert_equal david.projects, david.projects.reload.reload
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_proxy_association_accessor
|
||||||
|
david = developers(:david)
|
||||||
|
assert_equal david.association(:projects), david.projects.proxy_association
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class OverridingAssociationsTest < ActiveRecord::TestCase
|
class OverridingAssociationsTest < ActiveRecord::TestCase
|
||||||
|
|
Loading…
Reference in a new issue