Class: ActiveRecord::Associations::AssociationProxy
- Inherits:
-
Object
- Object
- ActiveRecord::Associations::AssociationProxy
- Defined in:
- lib/active_record/associations/association_proxy.rb
Overview
Active Record Associations
This is the root class of all association proxies:
AssociationProxy
BelongsToAssociation
HasOneAssociation
BelongsToPolymorphicAssociation
AssociationCollection
HasAndBelongsToManyAssociation
HasManyAssociation
HasManyThroughAssociation
HasOneThroughAssociation
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.
Direct Known Subclasses
AssociationCollection, BelongsToAssociation, BelongsToPolymorphicAssociation, HasOneAssociation
Instance Method Summary collapse
-
#===(other) ⇒ Object
Forwards
===
explicitly to the target because the instance method removal above doesn’t catch it. -
#aliased_table_name ⇒ Object
Returns the name of the table of the related class:.
-
#conditions ⇒ Object
(also: #sql_conditions)
Returns the SQL string that corresponds to the
:conditions
option of the macro, if given, ornil
otherwise. -
#initialize(owner, reflection) ⇒ AssociationProxy
constructor
A new instance of AssociationProxy.
-
#inspect ⇒ Object
Forwards the call to the target.
-
#loaded ⇒ Object
Asserts the target has been loaded setting the loaded flag to
true
. -
#loaded? ⇒ Boolean
Has the target been already loaded?.
-
#proxy_owner ⇒ Object
Returns the owner of the proxy.
-
#proxy_reflection ⇒ Object
Returns the reflection object that represents the association handled by the proxy.
-
#proxy_respond_to? ⇒ Object
:nodoc:.
-
#proxy_target ⇒ Object
Returns the target of the proxy, same as
target
. -
#reload ⇒ Object
Reloads the target and returns
self
on success. -
#reset ⇒ Object
Resets the loaded flag to
false
and sets the target tonil
. -
#respond_to?(*args) ⇒ Boolean
Does the proxy or its target respond to
symbol
?. - #send(method, *args) ⇒ Object
-
#target ⇒ Object
Returns the target of this proxy, same as
proxy_target
. -
#target=(target) ⇒ Object
Sets the target of this proxy to
\target
, and the loaded flag totrue
.
Constructor Details
#initialize(owner, reflection) ⇒ AssociationProxy
Returns a new instance of AssociationProxy.
58 59 60 61 62 63 64 |
# File '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 end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object (private)
Forwards any missing method call to the target.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/active_record/associations/association_proxy.rb', line 212 def method_missing(method, *args) if load_target unless @target.respond_to?(method) = "undefined method `#{method.to_s}' for \"#{@target}\":#{@target.class.to_s}" raise NoMethodError, end if block_given? @target.send(method, *args) { |*block_args| yield(*block_args) } else @target.send(method, *args) end end end |
Instance Method Details
#===(other) ⇒ Object
Forwards ===
explicitly to the target because the instance method removal above doesn’t catch it. Loads the target if needed.
89 90 91 92 |
# File 'lib/active_record/associations/association_proxy.rb', line 89 def ===(other) load_target other === @target end |
#aliased_table_name ⇒ Object
Returns the name of the table of the related class:
post.comments.aliased_table_name # => "comments"
98 99 100 |
# File 'lib/active_record/associations/association_proxy.rb', line 98 def aliased_table_name @reflection.klass.table_name end |
#conditions ⇒ Object Also known as: sql_conditions
Returns the SQL string that corresponds to the :conditions
option of the macro, if given, or nil
otherwise.
104 105 106 |
# File 'lib/active_record/associations/association_proxy.rb', line 104 def conditions @conditions ||= interpolate_sanitized_sql(@reflection.sanitized_conditions) if @reflection.sanitized_conditions end |
#inspect ⇒ Object
Forwards the call to the target. Loads the target if needed.
144 145 146 147 |
# File 'lib/active_record/associations/association_proxy.rb', line 144 def inspect load_target @target.inspect end |
#loaded ⇒ Object
Asserts the target has been loaded setting the loaded flag to true
.
128 129 130 |
# File 'lib/active_record/associations/association_proxy.rb', line 128 def loaded @loaded = true end |
#loaded? ⇒ Boolean
Has the target been already loaded?
123 124 125 |
# File 'lib/active_record/associations/association_proxy.rb', line 123 def loaded? @loaded end |
#proxy_owner ⇒ Object
Returns the owner of the proxy.
67 68 69 |
# File 'lib/active_record/associations/association_proxy.rb', line 67 def proxy_owner @owner end |
#proxy_reflection ⇒ Object
Returns the reflection object that represents the association handled by the proxy.
73 74 75 |
# File 'lib/active_record/associations/association_proxy.rb', line 73 def proxy_reflection @reflection end |
#proxy_respond_to? ⇒ Object
:nodoc:
53 |
# File 'lib/active_record/associations/association_proxy.rb', line 53 alias_method :proxy_respond_to?, :respond_to? |
#proxy_target ⇒ Object
Returns the target of the proxy, same as target
.
78 79 80 |
# File 'lib/active_record/associations/association_proxy.rb', line 78 def proxy_target @target end |
#reload ⇒ Object
Reloads the target and returns self
on success.
116 117 118 119 120 |
# File 'lib/active_record/associations/association_proxy.rb', line 116 def reload reset load_target self unless @target.nil? end |
#reset ⇒ Object
Resets the loaded flag to false
and sets the target to nil
.
110 111 112 113 |
# File 'lib/active_record/associations/association_proxy.rb', line 110 def reset @loaded = false @target = nil end |
#respond_to?(*args) ⇒ Boolean
Does the proxy or its target respond to symbol
?
83 84 85 |
# File 'lib/active_record/associations/association_proxy.rb', line 83 def respond_to?(*args) proxy_respond_to?(*args) || (load_target && @target.respond_to?(*args)) end |
#send(method, *args) ⇒ Object
149 150 151 152 153 154 155 156 |
# File 'lib/active_record/associations/association_proxy.rb', line 149 def send(method, *args) if proxy_respond_to?(method) super else load_target @target.send(method, *args) end end |
#target ⇒ Object
Returns the target of this proxy, same as proxy_target
.
133 134 135 |
# File 'lib/active_record/associations/association_proxy.rb', line 133 def target @target end |
#target=(target) ⇒ Object
Sets the target of this proxy to \target
, and the loaded flag to true
.
138 139 140 141 |
# File 'lib/active_record/associations/association_proxy.rb', line 138 def target=(target) @target = target loaded end |