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:
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.
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:.
-
- (Object) conditions
(also: #sql_conditions)
Returns the SQL string that corresponds to the :conditions option of the macro, if given, or nil otherwise.
-
- (Object) flatten_deeper(array)
Array#flatten has problems with recursive arrays before Ruby 1.9.2.
-
- (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) proxy_owner
Returns the owner of the proxy.
-
- (Object) proxy_reflection
Returns the reflection object that represents the association handled by the proxy.
-
- (Object) proxy_respond_to?
:nodoc:.
-
- (Object) proxy_target
Returns the target of the proxy, same as target.
-
- (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) send(method, *args)
-
- (Object) target
Returns the target of this proxy, same as proxy_target.
-
- (Object) target=(target)
Sets the target of this proxy to \target, and the loaded flag to true.
Constructor Details
- (AssociationProxy) initialize(owner, reflection)
A new instance of AssociationProxy
58 59 60 61 62 63 64 |
# 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 end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
- (Object) method_missing(method, *args) (private)
Forwards any missing method call to the target.
208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 208 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
- (Object) ===(other)
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 'activerecord/lib/active_record/associations/association_proxy.rb', line 89 def ===(other) load_target other === @target end |
- (Object) aliased_table_name
Returns the name of the table of the related class:
post.comments.aliased_table_name # => "comments"
98 99 100 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 98 def aliased_table_name @reflection.klass.table_name end |
- (Object) conditions 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 'activerecord/lib/active_record/associations/association_proxy.rb', line 104 def conditions @conditions ||= interpolate_sql(@reflection.sanitized_conditions) if @reflection.sanitized_conditions end |
- (Object) flatten_deeper(array)
Array#flatten has problems with recursive arrays before Ruby 1.9.2. Going one level deeper solves the majority of the problems.
267 268 269 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 267 def flatten_deeper(array) array.flatten end |
- (Object) inspect
Forwards the call to the target. Loads the target if needed.
144 145 146 147 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 144 def inspect load_target @target.inspect end |
- (Object) loaded
Asserts the target has been loaded setting the loaded flag to true.
128 129 130 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 128 def loaded @loaded = true end |
- (Boolean) loaded?
Has the target been already loaded?
123 124 125 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 123 def loaded? @loaded end |
- (Object) proxy_owner
Returns the owner of the proxy.
67 68 69 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 67 def proxy_owner @owner end |
- (Object) proxy_reflection
Returns the reflection object that represents the association handled by the proxy.
73 74 75 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 73 def proxy_reflection @reflection end |
- (Object) proxy_respond_to?
:nodoc:
53 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 53 alias_method :proxy_respond_to?, :respond_to? |
- (Object) proxy_target
Returns the target of the proxy, same as target.
78 79 80 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 78 def proxy_target @target end |
- (Object) reload
Reloads the target and returns self on success.
116 117 118 119 120 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 116 def reload reset load_target self unless @target.nil? end |
- (Object) reset
Resets the loaded flag to false and sets the target to nil.
110 111 112 113 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 110 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) proxy_respond_to?(*args) || (load_target && @target.respond_to?(*args)) end |
- (Object) send(method, *args)
149 150 151 152 153 154 155 156 |
# File 'activerecord/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 |
- (Object) target
Returns the target of this proxy, same as proxy_target.
133 134 135 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 133 def target @target end |
- (Object) target=(target)
Sets the target of this proxy to \target, and the loaded flag to true.
138 139 140 141 |
# File 'activerecord/lib/active_record/associations/association_proxy.rb', line 138 def target=(target) @target = target loaded end |