#primary_key(klass) (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 356
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 this association has a counter cache and its column values were backfilled (and so it is used internally by methods like size
/any?
/etc).
Returns whether this association has a counter cache.
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 164
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 324
def counter_must_be_updated_by_has_many? !inverse_updates_counter_in_memory? && has_cached_counter? end
Boolean
(readonly)
Returns whether this association has a counter cache and its column values were backfilled (and so it is used internally by methods like size
/any?
/etc).
# File 'activerecord/lib/active_record/reflection.rb', line 315
def has_active_cached_counter? return false unless has_cached_counter? counter_cache = [:counter_cache] || (inverse_which_updates_counter_cache && inverse_which_updates_counter_cache. [:counter_cache]) counter_cache[:active] != false end
Boolean
(readonly)
Returns whether this association has a counter cache.
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 307
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 297
alias inverse_updates_counter_cache? inverse_which_updates_counter_cache
Boolean
(readonly)
# File 'activerecord/lib/active_record/reflection.rb', line 299
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 340
def strict_loading? [:strict_loading] end
Boolean
(readonly)
# File 'activerecord/lib/active_record/reflection.rb', line 172
def through_reflection? false end
FIXME: this is a horrible name
# File 'activerecord/lib/active_record/reflection.rb', line 351
def actual_source_reflection # FIXME: this is a horrible name self end
# File 'activerecord/lib/active_record/reflection.rb', line 328
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 182
def build_association(attributes, &block) klass.new(attributes, &block) end
# File 'activerecord/lib/active_record/reflection.rb', line 332
def chain collect_join_chain end
# File 'activerecord/lib/active_record/reflection.rb', line 264
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 190
def class_name @class_name ||= -( [:class_name] || derive_class_name).to_s end
# File 'activerecord/lib/active_record/reflection.rb', line 244
def counter_cache_column @counter_cache_column ||= begin counter_cache = [:counter_cache] if belongs_to? if counter_cache counter_cache[:column] || -"#{active_record.name.demodulize.underscore.pluralize}_count" end else -((counter_cache && -counter_cache[:column]) || "#{name}_count") end end end
# File 'activerecord/lib/active_record/reflection.rb', line 360
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 258
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 285
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 200
def join_scope(table, foreign_table, foreign_klass) predicate_builder = klass.predicate_builder.with(TableMetadata.new(klass, 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 227
def join_scopes(table, predicate_builder = nil, 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 235
def klass_join_scope(table, predicate_builder = nil) # :nodoc: relation = build_scope(table, predicate_builder) klass.scope_for_association(relation) end
# File 'activerecord/lib/active_record/reflection.rb', line 356
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 196
def scopes scope ? [scope] : [] end
# File 'activerecord/lib/active_record/reflection.rb', line 344
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 176
def table_name klass.table_name end