Class: ActiveRecord::Reflection::AbstractReflection
- Inherits:
-
Object
- Object
- ActiveRecord::Reflection::AbstractReflection
- Defined in:
- lib/active_record/reflection.rb
Overview
Holds all the methods that are shared between MacroReflection and ThroughReflection.
AbstractReflection
MacroReflection
AggregateReflection
AssociationReflection
HasManyReflection
HasOneReflection
BelongsToReflection
HasAndBelongsToManyReflection
ThroughReflection
PolymorphicReflection
RuntimeReflection
Direct Known Subclasses
MacroReflection, PolymorphicReflection, RuntimeReflection, ThroughReflection
Instance Method Summary collapse
- #alias_candidate(name) ⇒ Object
-
#build_association(attributes, &block) ⇒ Object
Returns a new, unsaved instance of the associated class.
- #build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass) ⇒ Object
- #chain ⇒ Object
- #check_validity_of_inverse! ⇒ Object
-
#class_name ⇒ Object
Returns the class name for the macro.
- #constraints ⇒ Object
- #counter_cache_column ⇒ Object
- #counter_must_be_updated_by_has_many? ⇒ Boolean
-
#has_cached_counter? ⇒ Boolean
Returns whether a counter cache should be used for this association.
- #inverse_of ⇒ Object
- #inverse_updates_counter_in_memory? ⇒ Boolean
-
#inverse_which_updates_counter_cache ⇒ Object
(also: #inverse_updates_counter_cache?)
We need to avoid the following situation:.
- #join_scope(table, foreign_table, foreign_klass) ⇒ Object
-
#join_scopes(table, predicate_builder, klass = self.klass, record = nil) ⇒ Object
:nodoc:.
-
#klass_join_scope(table, predicate_builder) ⇒ Object
:nodoc:.
-
#scopes ⇒ Object
Returns a list of scopes that should be applied for this Reflection object when querying the database.
- #strict_loading? ⇒ Boolean
- #table_name ⇒ Object
-
#through_reflection? ⇒ Boolean
:nodoc:.
Instance Method Details
#alias_candidate(name) ⇒ Object
280 281 282 |
# File 'lib/active_record/reflection.rb', line 280 def alias_candidate(name) "#{plural_name}_#{name}" end |
#build_association(attributes, &block) ⇒ Object
Returns a new, unsaved instance of the associated class. attributes
will be passed to the class’s constructor.
157 158 159 |
# File 'lib/active_record/reflection.rb', line 157 def build_association(attributes, &block) klass.new(attributes, &block) end |
#build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass) ⇒ Object
288 289 290 291 292 293 294 |
# File 'lib/active_record/reflection.rb', line 288 def build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass) Relation.create( klass, table: table, predicate_builder: predicate_builder ) end |
#chain ⇒ Object
284 285 286 |
# File 'lib/active_record/reflection.rb', line 284 def chain collect_join_chain end |
#check_validity_of_inverse! ⇒ Object
233 234 235 236 237 238 239 240 241 242 |
# File 'lib/active_record/reflection.rb', line 233 def check_validity_of_inverse! unless polymorphic? if has_inverse? && inverse_of.nil? raise InverseOfAssociationNotFoundError.new(self) end if has_inverse? && inverse_of == self raise InverseOfAssociationRecursiveError.new(self) end end end |
#class_name ⇒ Object
Returns the class name for the macro.
composed_of :balance, class_name: 'Money'
returns 'Money'
has_many :clients
returns 'Client'
165 166 167 |
# File 'lib/active_record/reflection.rb', line 165 def class_name @class_name ||= -([:class_name] || derive_class_name).to_s end |
#constraints ⇒ Object
211 212 213 |
# File 'lib/active_record/reflection.rb', line 211 def constraints chain.flat_map(&:scopes) end |
#counter_cache_column ⇒ Object
215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/active_record/reflection.rb', line 215 def counter_cache_column @counter_cache_column ||= if belongs_to? if [:counter_cache] == true -"#{active_record.name.demodulize.underscore.pluralize}_count" elsif [:counter_cache] -[:counter_cache].to_s end else -([:counter_cache]&.to_s || "#{name}_count") end end |
#counter_must_be_updated_by_has_many? ⇒ Boolean
276 277 278 |
# File 'lib/active_record/reflection.rb', line 276 def counter_must_be_updated_by_has_many? !inverse_updates_counter_in_memory? && has_cached_counter? end |
#has_cached_counter? ⇒ Boolean
Returns whether a counter cache should be used for this association.
The counter_cache option must be given on either the owner or inverse association, and the column must be present on the owner.
270 271 272 273 274 |
# File 'lib/active_record/reflection.rb', line 270 def has_cached_counter? [:counter_cache] || inverse_which_updates_counter_cache && inverse_which_updates_counter_cache.[:counter_cache] && active_record.has_attribute?(counter_cache_column) end |
#inverse_of ⇒ Object
227 228 229 230 231 |
# File 'lib/active_record/reflection.rb', line 227 def inverse_of return unless inverse_name @inverse_of ||= klass._reflect_on_association inverse_name end |
#inverse_updates_counter_in_memory? ⇒ Boolean
262 263 264 |
# File 'lib/active_record/reflection.rb', line 262 def inverse_updates_counter_in_memory? inverse_of && inverse_which_updates_counter_cache == inverse_of end |
#inverse_which_updates_counter_cache ⇒ Object Also known as: inverse_updates_counter_cache?
We need to avoid the following situation:
* An associated record is deleted via record.destroy
* Hence the callbacks run, and they find a belongs_to on the record with a
:counter_cache options which points back at our owner. So they update the
counter cache.
* In which case, we must make sure to *not* update the counter cache, or else
it will be decremented twice.
Hence this method.
254 255 256 257 258 259 |
# File 'lib/active_record/reflection.rb', line 254 def inverse_which_updates_counter_cache return @inverse_which_updates_counter_cache if defined?(@inverse_which_updates_counter_cache) @inverse_which_updates_counter_cache = klass.reflect_on_all_associations(:belongs_to).find do |inverse| inverse.counter_cache_column == counter_cache_column end end |
#join_scope(table, foreign_table, foreign_klass) ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/active_record/reflection.rb', line 175 def join_scope(table, foreign_table, foreign_klass) predicate_builder = predicate_builder(table) scope_chain_items = join_scopes(table, predicate_builder) klass_scope = klass_join_scope(table, predicate_builder) if type klass_scope.where!(type => foreign_klass.polymorphic_name) end scope_chain_items.inject(klass_scope, &:merge!) primary_key = join_primary_key foreign_key = join_foreign_key klass_scope.where!(table[primary_key].eq(foreign_table[foreign_key])) if klass.finder_needs_type_condition? klass_scope.where!(klass.send(:type_condition, table)) end klass_scope end |
#join_scopes(table, predicate_builder, klass = self.klass, record = nil) ⇒ Object
:nodoc:
198 199 200 201 202 203 204 |
# File 'lib/active_record/reflection.rb', line 198 def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc: if scope [scope_for(build_scope(table, predicate_builder, klass), record)] else [] end end |
#klass_join_scope(table, predicate_builder) ⇒ Object
:nodoc:
206 207 208 209 |
# File 'lib/active_record/reflection.rb', line 206 def klass_join_scope(table, predicate_builder) # :nodoc: relation = build_scope(table, predicate_builder) klass.scope_for_association(relation) end |
#scopes ⇒ Object
Returns a list of scopes that should be applied for this Reflection object when querying the database.
171 172 173 |
# File 'lib/active_record/reflection.rb', line 171 def scopes scope ? [scope] : [] end |
#strict_loading? ⇒ Boolean
296 297 298 |
# File 'lib/active_record/reflection.rb', line 296 def strict_loading? [:strict_loading] end |
#table_name ⇒ Object
151 152 153 |
# File 'lib/active_record/reflection.rb', line 151 def table_name klass.table_name end |
#through_reflection? ⇒ Boolean
:nodoc:
147 148 149 |
# File 'lib/active_record/reflection.rb', line 147 def through_reflection? false end |