Class: ActiveRecord::Associations::AssociationProxy
- Inherits:
-
Object
- Object
- ActiveRecord::Associations::AssociationProxy
- Defined in:
- activerecord/lib/active_record/associations/association_proxy.rb
Overview
Active Record Associations
This is the root class of all association proxies ('+ Foo' signifies an included module Foo):
AssociationProxy
SingularAssociaton
HasOneAssociation
HasOneThroughAssociation + ThroughAssociation
BelongsToAssociation
BelongsToPolymorphicAssociation
AssociationCollection
HasAndBelongsToManyAssociation
HasManyAssociation
HasManyThroughAssociation + ThroughAssociation
Association proxies in Active Record are middlemen between the object that holds the association, known as the @owner, and the actual associated object, known as the @target. The kind of association any proxy is about is available in @reflection. That's an instance of the class ActiveRecord::Reflection::AssociationReflection.
For example, given
class Blog < ActiveRecord::Base
has_many :posts
end
blog = Blog.find(:first)
the association proxy in blog.posts has the object in blog as @owner, the collection of its posts as @target, and the @reflection object represents a :has_many macro.
This class has most of the basic instance methods removed, and delegates unknown methods to @target via method_missing. As a corner case, it even removes the class method and that's why you get
blog.posts.class # => Array
though the object behind blog.posts is not an Array, but an ActiveRecord::Associations::HasManyAssociation.
The @target object is not loaded until needed. For example,
blog.posts.count
is computed directly through SQL and does not trigger by itself the instantiation of the actual post records.
Instance Attribute Summary (collapse)
-
- (Object) target
(also: #proxy_target)
Returns the target of this proxy, same as proxy_target.
Instance Method Summary (collapse)
-
- (Object) ===(other)
Forwards === explicitly to the target because the instance method removal above doesn't catch it.
-
- (Object) aliased_table_name
Returns the name of the table of the related class:.
-
- (AssociationProxy) initialize(owner, reflection)
constructor
A new instance of AssociationProxy.
-
- (Object) inspect
Forwards the call to the target.
-
- (Object) loaded!
Asserts the target has been loaded setting the loaded flag to true.
-
- (Boolean) loaded?
Has the target been already loaded?.
-
- (Object) method_missing(method, *args, &block)
Forwards any missing method call to the target.
-
- (Object) proxy_owner
Returns the owner of the proxy.
-
- (Object) proxy_reflection
Returns the reflection object that represents the association handled by the proxy.
-
- (Object) reload
Reloads the target and returns self on success.
-
- (Object) reset
Resets the loaded flag to false and sets the target to nil.
-
- (Boolean) respond_to?(*args)
Does the proxy or its target respond to symbol?.
- - (Object) scoped
- - (Object) send(method, *args)
-
- (Boolean) stale_target?
The target is stale if the target no longer points to the record(s) that the relevant foreign_key(s) refers to.
- - (Object) to_param
Constructor Details
- (AssociationProxy) initialize(owner, reflection)
A new instance of AssociationProxy
58 59 60 61 62 63 64 65 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 58 def initialize(owner, reflection) @owner, @reflection = owner, reflection @updated = false reflection.check_validity! Array.wrap(reflection.[:extend]).each { |ext| proxy_extend(ext) } reset construct_scope end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
- (Object) method_missing(method, *args, &block)
Forwards any missing method call to the target.
88 89 90 91 92 93 94 95 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 88 def method_missing(method, *args, &block) if load_target return super unless @target.respond_to?(method) @target.send(method, *args, &block) end rescue NoMethodError => e raise e, e..sub(/ for #<.*$/, " via proxy for #{@target}") end |
Instance Attribute Details
- (Object) target Also known as: proxy_target
Returns the target of this proxy, same as proxy_target.
147 148 149 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 147 def target @target end |
Instance Method Details
- (Object) ===(other)
Forwards === explicitly to the target because the instance method removal above doesn't catch it. Loads the target if needed.
99 100 101 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 99 def ===(other) other === load_target end |
- (Object) aliased_table_name
Returns the name of the table of the related class:
post.comments.aliased_table_name # => "comments"
107 108 109 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 107 def aliased_table_name @reflection.klass.table_name end |
- (Object) inspect
Forwards the call to the target. Loads the target if needed.
159 160 161 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 159 def inspect load_target.inspect end |
- (Object) loaded!
Asserts the target has been loaded setting the loaded flag to true.
131 132 133 134 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 131 def loaded! @loaded = true @stale_state = stale_state end |
- (Boolean) loaded?
Has the target been already loaded?
126 127 128 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 126 def loaded? @loaded end |
- (Object) proxy_owner
Returns the owner of the proxy.
72 73 74 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 72 def proxy_owner @owner end |
- (Object) proxy_reflection
Returns the reflection object that represents the association handled by the proxy.
78 79 80 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 78 def proxy_reflection @reflection end |
- (Object) reload
Reloads the target and returns self on success.
118 119 120 121 122 123 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 118 def reload reset construct_scope load_target self unless @target.nil? end |
- (Object) reset
Resets the loaded flag to false and sets the target to nil.
112 113 114 115 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 112 def reset @loaded = false @target = nil end |
- (Boolean) respond_to?(*args)
Does the proxy or its target respond to symbol?
83 84 85 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 83 def respond_to?(*args) super || (load_target && @target.respond_to?(*args)) end |
- (Object) scoped
168 169 170 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 168 def scoped target_scope & @association_scope end |
- (Object) send(method, *args)
163 164 165 166 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 163 def send(method, *args) return super if respond_to?(method) load_target.send(method, *args) end |
- (Boolean) stale_target?
The target is stale if the target no longer points to the record(s) that the relevant foreign_key(s) refers to. If stale, the association accessor method on the owner will reload the target. It's up to subclasses to implement the state_state method if relevant.
Note that if the target has not been loaded, it is not considered stale.
142 143 144 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 142 def stale_target? loaded? && @stale_state != stale_state end |
- (Object) to_param
67 68 69 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 67 def to_param proxy_target.to_param end |