#primary_key(klass) (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 344
def primary_key(klass) klass.primary_key || raise(UnknownPrimaryKey.new(klass)) end
123456789_123456789_123456789_123456789_123456789_
Relationships & Source Files | |
Extension / Inclusion / Inheritance Descendants | |
Subclasses:
AggregateReflection, AssociationReflection, BelongsToReflection, HasAndBelongsToManyReflection, HasManyReflection, HasOneReflection, MacroReflection, PolymorphicReflection, RuntimeReflection, ThroughReflection, ActiveStorage::Reflection::HasAttachedReflection, ActiveStorage::Reflection::HasManyAttachedReflection, ActiveStorage::Reflection::HasOneAttachedReflection
|
|
Inherits: | Object |
Defined in: | activerecord/lib/active_record/reflection.rb |
Holds all the methods that are shared between MacroReflection
and ThroughReflection
.
AbstractReflection
MacroReflection
AggregateReflection
AssociationReflection
HasManyReflection
HasOneReflection
BelongsToReflection
HasAndBelongsToManyReflection
ThroughReflection
PolymorphicReflection
RuntimeReflection
Returns whether a counter cache should be used for this association.
Alias for #inverse_which_updates_counter_cache.
Returns a new, unsaved instance of the associated class.
Returns the class name for the macro.
We need to avoid the following situation:
Returns a list of scopes that should be applied for this ::ActiveRecord::Reflection
object when querying the database.
FIXME: this is a horrible name.
AbstractReflection
# File 'activerecord/lib/active_record/reflection.rb', line 157
def initialize @class_name = nil @counter_cache_column = nil @inverse_of = nil @inverse_which_updates_counter_cache_defined = false @inverse_which_updates_counter_cache = nil end
Boolean
(readonly)
# File 'activerecord/lib/active_record/reflection.rb', line 304
def counter_must_be_updated_by_has_many? !inverse_updates_counter_in_memory? && has_cached_counter? end
Boolean
(readonly)
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.
# File 'activerecord/lib/active_record/reflection.rb', line 298
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
Alias for #inverse_which_updates_counter_cache.
# File 'activerecord/lib/active_record/reflection.rb', line 288
alias inverse_updates_counter_cache? inverse_which_updates_counter_cache
Boolean
(readonly)
# File 'activerecord/lib/active_record/reflection.rb', line 290
def inverse_updates_counter_in_memory? inverse_of && inverse_which_updates_counter_cache == inverse_of end
Boolean
(readonly)
# File 'activerecord/lib/active_record/reflection.rb', line 324
def strict_loading? [:strict_loading] end
Boolean
(readonly)
# File 'activerecord/lib/active_record/reflection.rb', line 165
def through_reflection? false end
FIXME: this is a horrible name
# File 'activerecord/lib/active_record/reflection.rb', line 335
def actual_source_reflection # FIXME: this is a horrible name self end
# File 'activerecord/lib/active_record/reflection.rb', line 308
def alias_candidate(name) "#{plural_name}_#{name}" end
Returns a new, unsaved instance of the associated class. attributes
will be passed to the class’s constructor.
# File 'activerecord/lib/active_record/reflection.rb', line 175
def build_association(attributes, &block) klass.new(attributes, &block) end
# File 'activerecord/lib/active_record/reflection.rb', line 316
def build_scope(table, predicate_builder = predicate_builder(table), klass = self.klass) Relation.create( klass, table: table, predicate_builder: predicate_builder ) end
# File 'activerecord/lib/active_record/reflection.rb', line 312
def chain collect_join_chain end
# File 'activerecord/lib/active_record/reflection.rb', line 255
def check_validity_of_inverse! if !polymorphic? && has_inverse? if inverse_of.nil? raise InverseOfAssociationNotFoundError.new(self) end if inverse_of == self raise InverseOfAssociationRecursiveError.new(self) end end end
Returns the class name for the macro.
composed_of :balance, class_name: 'Money'
returns 'Money'
has_many :clients
returns 'Client'
# File 'activerecord/lib/active_record/reflection.rb', line 183
def class_name @class_name ||= -( [:class_name] || derive_class_name).to_s end
# File 'activerecord/lib/active_record/reflection.rb', line 237
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
# File 'activerecord/lib/active_record/reflection.rb', line 348
def ensure_option_not_given_as_class!(option_name) if [option_name] && [option_name].class == Class raise ArgumentError, "A class was passed to `:#{option_name}` but we are expecting a string." end end
# File 'activerecord/lib/active_record/reflection.rb', line 249
def inverse_of return unless inverse_name @inverse_of ||= klass._reflect_on_association inverse_name end
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 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.
# File 'activerecord/lib/active_record/reflection.rb', line 276
def inverse_which_updates_counter_cache unless @inverse_which_updates_counter_cache_defined if counter_cache_column inverse_candidates = inverse_of ? [inverse_of] : klass.reflect_on_all_associations(:belongs_to) @inverse_which_updates_counter_cache = inverse_candidates.find do |inverse| inverse.counter_cache_column == counter_cache_column && (inverse.polymorphic? || inverse.klass == active_record) end end @inverse_which_updates_counter_cache_defined = true end @inverse_which_updates_counter_cache end
# File 'activerecord/lib/active_record/reflection.rb', line 193
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_column_names = Array(join_primary_key) foreign_key_column_names = Array(join_foreign_key) primary_foreign_key_pairs = primary_key_column_names.zip(foreign_key_column_names) primary_foreign_key_pairs.each do |primary_key_column_name, foreign_key_column_name| klass_scope.where!(table[primary_key_column_name].eq(foreign_table[foreign_key_column_name])) end if klass.finder_needs_type_condition? klass_scope.where!(klass.send(:type_condition, table)) end klass_scope end
# File 'activerecord/lib/active_record/reflection.rb', line 220
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
# File 'activerecord/lib/active_record/reflection.rb', line 228
def klass_join_scope(table, predicate_builder) # :nodoc: relation = build_scope(table, predicate_builder) klass.scope_for_association(relation) end
# File 'activerecord/lib/active_record/reflection.rb', line 340
def predicate_builder(table) PredicateBuilder.new(TableMetadata.new(klass, table)) end
# File 'activerecord/lib/active_record/reflection.rb', line 344
def primary_key(klass) klass.primary_key || raise(UnknownPrimaryKey.new(klass)) end
Returns a list of scopes that should be applied for this ::ActiveRecord::Reflection
object when querying the database.
# File 'activerecord/lib/active_record/reflection.rb', line 189
def scopes scope ? [scope] : [] end
# File 'activerecord/lib/active_record/reflection.rb', line 328
def (owner) = +"`#{owner}` is marked for strict_loading." << " The #{polymorphic? ? "polymorphic association" : "#{klass} association"}" << " named `:#{name}` cannot be lazily loaded." end
# File 'activerecord/lib/active_record/reflection.rb', line 169
def table_name klass.table_name end