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?)
This shit is nasty.
- #join_scope(table, foreign_table, foreign_klass) ⇒ Object
-
#join_scopes(table, predicate_builder, klass = self.klass) ⇒ 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
276 277 278 |
# File 'lib/active_record/reflection.rb', line 276 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.
156 157 158 |
# File 'lib/active_record/reflection.rb', line 156 def build_association(attributes, &block) klass.new(attributes, &block) end |
#build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass) ⇒ Object
284 285 286 287 288 289 290 |
# File 'lib/active_record/reflection.rb', line 284 def build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass) Relation.create( klass, table: table, predicate_builder: predicate_builder ) end |
#chain ⇒ Object
280 281 282 |
# File 'lib/active_record/reflection.rb', line 280 def chain collect_join_chain end |
#check_validity_of_inverse! ⇒ Object
232 233 234 235 236 237 238 |
# File 'lib/active_record/reflection.rb', line 232 def check_validity_of_inverse! unless polymorphic? if has_inverse? && inverse_of.nil? raise InverseOfAssociationNotFoundError.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'
164 165 166 |
# File 'lib/active_record/reflection.rb', line 164 def class_name @class_name ||= -([:class_name] || derive_class_name).to_s end |
#constraints ⇒ Object
210 211 212 |
# File 'lib/active_record/reflection.rb', line 210 def constraints chain.flat_map(&:scopes) end |
#counter_cache_column ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/active_record/reflection.rb', line 214 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
272 273 274 |
# File 'lib/active_record/reflection.rb', line 272 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.
266 267 268 269 270 |
# File 'lib/active_record/reflection.rb', line 266 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
226 227 228 229 230 |
# File 'lib/active_record/reflection.rb', line 226 def inverse_of return unless inverse_name @inverse_of ||= klass._reflect_on_association inverse_name end |
#inverse_updates_counter_in_memory? ⇒ Boolean
258 259 260 |
# File 'lib/active_record/reflection.rb', line 258 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?
This shit is nasty. 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.
250 251 252 253 254 255 |
# File 'lib/active_record/reflection.rb', line 250 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
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/active_record/reflection.rb', line 174 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) ⇒ Object
:nodoc:
197 198 199 200 201 202 203 |
# File 'lib/active_record/reflection.rb', line 197 def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc: if scope [scope_for(build_scope(table, predicate_builder, klass))] else [] end end |
#klass_join_scope(table, predicate_builder) ⇒ Object
:nodoc:
205 206 207 208 |
# File 'lib/active_record/reflection.rb', line 205 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.
170 171 172 |
# File 'lib/active_record/reflection.rb', line 170 def scopes scope ? [scope] : [] end |
#strict_loading? ⇒ Boolean
292 293 294 |
# File 'lib/active_record/reflection.rb', line 292 def strict_loading? [:strict_loading] end |
#table_name ⇒ Object
150 151 152 |
# File 'lib/active_record/reflection.rb', line 150 def table_name klass.table_name end |
#through_reflection? ⇒ Boolean
:nodoc:
146 147 148 |
# File 'lib/active_record/reflection.rb', line 146 def through_reflection? false end |