Class: ActiveRecord::Associations::Association
- Inherits:
-
Object
- Object
- ActiveRecord::Associations::Association
- Defined in:
- lib/active_record/associations/association.rb
Overview
Active Record Associations
This is the root class of all associations (‘+ Foo’ signifies an included module Foo):
Association
SingularAssociation
HasOneAssociation
HasOneThroughAssociation + ThroughAssociation
BelongsToAssociation
BelongsToPolymorphicAssociation
CollectionAssociation
HasAndBelongsToManyAssociation
HasManyAssociation
HasManyThroughAssociation + ThroughAssociation
Direct Known Subclasses
Instance Attribute Summary collapse
-
#owner ⇒ Object
readonly
:nodoc:.
-
#reflection ⇒ Object
readonly
:nodoc:.
-
#target ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#aliased_table_name ⇒ Object
Returns the name of the table of the related class:.
-
#association_scope ⇒ Object
The scope for this association.
-
#initialize(owner, reflection) ⇒ Association
constructor
A new instance of Association.
- #interpolate(sql, record = nil) ⇒ Object
-
#klass ⇒ Object
This class of the target.
-
#load_target ⇒ Object
Loads the target if needed and returns it.
-
#loaded! ⇒ Object
Asserts the target has been loaded setting the loaded flag to
true
. -
#loaded? ⇒ Boolean
Has the target been already loaded?.
-
#reload ⇒ Object
Reloads the target and returns
self
on success. -
#reset ⇒ Object
Resets the loaded flag to
false
and sets the target tonil
. - #reset_scope ⇒ Object
- #scoped ⇒ Object
-
#set_inverse_instance(record) ⇒ Object
Set the inverse association, if possible.
-
#stale_target? ⇒ Boolean
The target is stale if the target no longer points to the record(s) that the relevant foreign_key(s) refers to.
-
#target_scope ⇒ Object
Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the through association’s scope).
Constructor Details
#initialize(owner, reflection) ⇒ Association
Returns a new instance of Association.
25 26 27 28 29 30 31 32 33 34 |
# File 'lib/active_record/associations/association.rb', line 25 def initialize(owner, reflection) reflection.check_validity! @target = nil @owner, @reflection = owner, reflection @updated = false reset reset_scope end |
Instance Attribute Details
#owner ⇒ Object (readonly)
:nodoc:
21 22 23 |
# File 'lib/active_record/associations/association.rb', line 21 def owner @owner end |
#reflection ⇒ Object (readonly)
:nodoc:
21 22 23 |
# File 'lib/active_record/associations/association.rb', line 21 def reflection @reflection end |
#target ⇒ Object
:nodoc:
21 22 23 |
# File 'lib/active_record/associations/association.rb', line 21 def target @target end |
Instance Method Details
#aliased_table_name ⇒ Object
Returns the name of the table of the related class:
post.comments.aliased_table_name # => "comments"
40 41 42 |
# File 'lib/active_record/associations/association.rb', line 40 def aliased_table_name reflection.klass.table_name end |
#association_scope ⇒ Object
The scope for this association.
Note that the association_scope is merged into the target_scope only when the scoped method is called. This is because at that point the call may be surrounded by scope.scoping { … } or with_scope { … } etc, which affects the scope which actually gets built.
97 98 99 100 101 |
# File 'lib/active_record/associations/association.rb', line 97 def association_scope if klass @association_scope ||= AssociationScope.new(self).scope end end |
#interpolate(sql, record = nil) ⇒ Object
160 161 162 163 164 165 166 |
# File 'lib/active_record/associations/association.rb', line 160 def interpolate(sql, record = nil) if sql.respond_to?(:to_proc) owner.send(:instance_exec, record, &sql) else sql end end |
#klass ⇒ Object
This class of the target. belongs_to polymorphic overrides this to look at the polymorphic_type field on the owner.
117 118 119 |
# File 'lib/active_record/associations/association.rb', line 117 def klass reflection.klass end |
#load_target ⇒ Object
Loads the target if needed and returns it.
This method is abstract in the sense that it relies on find_target
, which is expected to be provided by descendants.
If the target is stale(the target no longer points to the record(s) that the relevant foreign_key(s) refers to.), force reload the target.
Otherwise if the target is already loaded it is just returned. Thus, you can call load_target
unconditionally to get the target.
ActiveRecord::RecordNotFound is rescued within the method, and it is not reraised. The proxy is reset and nil
is the return value.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/active_record/associations/association.rb', line 140 def load_target if (@stale_state && stale_target?) || find_target? begin if IdentityMap.enabled? && association_class && association_class.respond_to?(:base_class) @target = IdentityMap.get(association_class, owner[reflection.foreign_key]) elsif @stale_state && stale_target? @target = find_target end rescue NameError nil ensure @target ||= find_target end end loaded! unless loaded? target rescue ActiveRecord::RecordNotFound reset end |
#loaded! ⇒ Object
Asserts the target has been loaded setting the loaded flag to true
.
66 67 68 69 |
# File 'lib/active_record/associations/association.rb', line 66 def loaded! @loaded = true @stale_state = stale_state end |
#loaded? ⇒ Boolean
Has the target been already loaded?
61 62 63 |
# File 'lib/active_record/associations/association.rb', line 61 def loaded? @loaded end |
#reload ⇒ Object
Reloads the target and returns self
on success.
53 54 55 56 57 58 |
# File 'lib/active_record/associations/association.rb', line 53 def reload reset reset_scope load_target self unless target.nil? end |
#reset ⇒ Object
Resets the loaded flag to false
and sets the target to nil
.
45 46 47 48 49 50 |
# File 'lib/active_record/associations/association.rb', line 45 def reset @loaded = false IdentityMap.remove(target) if IdentityMap.enabled? && target @target = nil @stale_state = nil end |
#reset_scope ⇒ Object
103 104 105 |
# File 'lib/active_record/associations/association.rb', line 103 def reset_scope @association_scope = nil end |
#scoped ⇒ Object
87 88 89 |
# File 'lib/active_record/associations/association.rb', line 87 def scoped target_scope.merge(association_scope) end |
#set_inverse_instance(record) ⇒ Object
Set the inverse association, if possible
108 109 110 111 112 113 |
# File 'lib/active_record/associations/association.rb', line 108 def set_inverse_instance(record) if record && invertible_for?(record) inverse = record.association(inverse_reflection_for(record).name) inverse.target = owner end end |
#stale_target? ⇒ Boolean
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.
77 78 79 |
# File 'lib/active_record/associations/association.rb', line 77 def stale_target? loaded? && @stale_state != stale_state end |
#target_scope ⇒ Object
Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the through association’s scope)
123 124 125 |
# File 'lib/active_record/associations/association.rb', line 123 def target_scope klass.scoped end |