Class: ActiveRecord::Reflection::AssociationReflection
| Relationships & Source Files | |
| Extension / Inclusion / Inheritance Descendants | |
|
Subclasses:
|
|
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
|
|
|
Instance Chain:
|
|
| Inherits: |
ActiveRecord::Reflection::MacroReflection
|
| Defined in: | activerecord/lib/active_record/reflection.rb |
Overview
Holds all the metadata about an association as it was specified in the Active Record class.
Constant Summary
-
FROZEN_EMPTY_ARRAY =
private
# File 'activerecord/lib/active_record/reflection.rb', line 585[].freeze
Class Method Summary
MacroReflection - Inherited
AbstractReflection - Inherited
Instance Attribute Summary
-
#belongs_to? ⇒ Boolean
readonly
Returns
trueifselfis abelongs_toreflection. -
#collection? ⇒ Boolean
readonly
Returns whether or not this association reflection is for a collection association.
- #deprecated? ⇒ Boolean readonly
- #extensions readonly
- #foreign_type readonly
- #has_inverse? ⇒ Boolean readonly
-
#has_one? ⇒ Boolean
readonly
Returns
trueifselfis ahas_onereflection. - #has_scope? ⇒ Boolean readonly
- #nested? ⇒ Boolean readonly
- #parent_reflection rw
- #polymorphic? ⇒ Boolean readonly
- #type readonly
-
#validate? ⇒ Boolean
readonly
Returns whether or not the association should be validated as part of the parent's validation.
MacroReflection - Inherited
| #active_record, #autosave=, | |
| #name | Returns the name of the macro. |
| #options | Returns the hash of options used for the macro. |
| #scope, #plural_name | |
AbstractReflection - Inherited
| #counter_must_be_updated_by_has_many?, | |
| #has_active_cached_counter? | Returns whether this association has a counter cache and its column values were backfilled (and so it is used internally by methods like |
| #has_cached_counter? | Returns whether this association has a counter cache. |
| #inverse_updates_counter_cache? | |
| #inverse_updates_counter_in_memory?, #strict_loading?, #through_reflection? | |
Instance Method Summary
- #active_record_primary_key
-
#active_record_primary_key_definition
Same as #active_record_primary_key but returns an
::ActiveRecord::Key. - #add_as_polymorphic_through(reflection, seed)
- #add_as_source(seed)
- #add_as_through(seed)
- #association_class
- #association_foreign_key
-
#association_foreign_key_definition
Same as #association_foreign_key but returns an
::ActiveRecord::Key. - #association_primary_key(klass = nil)
-
#association_primary_key_definition(klass = nil)
Same as #association_primary_key but returns an
::ActiveRecord::Key. - #association_route(origin_class: active_record, destination_class: nil)
- #association_route_chain(origin_class: active_record, destination_class: nil)
- #check_eager_loadable!
- #check_validity!
-
#clear_association_scope_cache(klass = self.klass)
Pass the concrete target class for polymorphic associations.
-
#collect_join_chain
A chain of reflections from this one back to the owner.
- #compute_class(name)
- #foreign_key(infer_from_inverse_of: true)
-
#foreign_key_definition(infer_from_inverse_of: true)
Same as #foreign_key but returns an
::ActiveRecord::Key. - #freeze
- #join_table
-
#macro
Returns the macro type.
- #polymorphic_inverse_of(associated_class)
- #polymorphic_name
-
#prepare_default_association_route
Resolves the default route ahead of the reflection being made shareable, so that every Ractor can read it from the frozen slot.
- #source_reflection
- #through_reflection
- #association_route_cache private
- #association_route_class private
- #association_route_constraints(_reference_class, _target_class) private
- #association_route_target_key(_target_class) private
-
#automatic_inverse_of
private
returns either
nilor the inverse association name that it finds. - #build_association_route(reference_class:, target_class:, fixed_values: {}) private
-
#can_find_inverse_of_automatically?(reflection, inverse_reflection = false) ⇒ Boolean
private
Checks to see if the reflection doesn't have any options that prevent us from being able to guess the inverse automatically.
-
#current_default_association_route?(slot) ⇒ Boolean
private
Compares loaded contexts by identity: a context matching the slot's was loaded when the slot was filled, so this needn't load anything.
-
#default_association_route
private
Slots contain [origin context, destination class, destination context, route].
- #default_destination_class private
- #derive_class_name private
- #derive_fk_query_constraints(foreign_key) private
- #derive_foreign_key(infer_from_inverse_of: true) private
- #derive_join_table private
- #initialize_copy(other) private
-
#inverse_name
private
Attempts to find the inverse association name automatically.
- #resolve_association_route(origin_class, destination_class) private
-
#scope_allows_automatic_inverse_of?(reflection, inverse_reflection) ⇒ Boolean
private
Scopes on the potential inverse reflection prevent automatic
inverse_of, since the scope could exclude the owner record we would inverse from. -
#valid_inverse_reflection?(reflection) ⇒ Boolean
private
Checks if the inverse reflection that is returned from the #automatic_inverse_of method is a valid reflection.
MacroReflection - Inherited
| #== | Returns |
| #compute_class, | |
| #klass | Returns the class for the macro. |
| #scope_for, #derive_class_name, #normalize_options, #_klass | |
AbstractReflection - Inherited
| #alias_candidate, #association_route_for_join, #association_scope_cache, | |
| #build_association | Returns a new, unsaved instance of the associated class. |
| #build_scope, #chain, #check_validity_of_inverse!, | |
| #class_name | Returns the class name for the macro. |
| #constraints, #counter_cache_column, #inverse_of, | |
| #inverse_which_updates_counter_cache | We need to avoid the following situation: |
| #join_scope, #join_scopes, #klass_join_scope, | |
| #scopes | Returns a list of scopes that should be applied for this |
| #strict_loading_violation_message, #table_name, | |
| #actual_source_reflection | FIXME: this is a horrible name. |
| #ensure_option_not_given_as_class!, | |
| #inferred_primary_key_definition | The Key form of a model's inferred primary key. |
| #primary_key, #primary_key_definition | |
Constructor Details
.new(name, scope, options, active_record) ⇒ AssociationReflection
# File 'activerecord/lib/active_record/reflection.rb', line 588
def initialize(name, scope, , active_record) super @validated = false @type = -([:foreign_type]&.to_s || "#{[:as]}_type") if [:as] @foreign_type = -([:foreign_type]&.to_s || "#{name}_type") if [:polymorphic] @join_table = nil @foreign_key_definition = nil @association_foreign_key_definition = nil @association_primary_key_definition = nil @active_record_primary_key_definition = nil @default_association_route = nil @default_association_route_key = :"active_record_default_association_route_#{object_id}" @extensions = [:extend] ? Array([:extend]) : FROZEN_EMPTY_ARRAY @extensions = @extensions.dup.freeze unless @extensions.frozen? if [:query_constraints] raise ConfigurationError, <<~MSG.squish Setting `query_constraints:` option on `#{active_record}.#{macro} :#{name}` is not allowed. To get the same behavior, use the `foreign_key` option instead. MSG end # If the foreign key is an array, set query constraints options and don't use the foreign key if [:foreign_key].is_a?(Array) [:query_constraints] = .delete(:foreign_key) end @deprecated = !![:deprecated] ensure_option_not_given_as_class!(:class_name) end
Instance Attribute Details
#belongs_to? ⇒ Boolean (readonly)
Returns true if self is a belongs_to reflection.
# File 'activerecord/lib/active_record/reflection.rb', line 824
def belongs_to?; false; end
#collection? ⇒ Boolean (readonly)
Returns whether or not this association reflection is for a collection
association. Returns true if the #macro is either has_many or
has_and_belongs_to_many, false otherwise.
# File 'activerecord/lib/active_record/reflection.rb', line 806
def collection? false end
#deprecated? ⇒ Boolean (readonly)
[ GitHub ]
# File 'activerecord/lib/active_record/reflection.rb', line 851
def deprecated? @deprecated end
#extensions (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 582
attr_reader :type, :foreign_type, :extensions
#foreign_type (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 582
attr_reader :type, :foreign_type, :extensions
#has_inverse? ⇒ Boolean (readonly)
[ GitHub ]
# File 'activerecord/lib/active_record/reflection.rb', line 784
def has_inverse? inverse_name end
#has_one? ⇒ Boolean (readonly)
Returns true if self is a has_one reflection.
# File 'activerecord/lib/active_record/reflection.rb', line 827
def has_one?; false; end
#has_scope? ⇒ Boolean (readonly)
[ GitHub ]
# File 'activerecord/lib/active_record/reflection.rb', line 780
def has_scope? scope end
#nested? ⇒ Boolean (readonly)
[ GitHub ]
# File 'activerecord/lib/active_record/reflection.rb', line 776
def nested? false end
#parent_reflection (rw)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 583
attr_accessor :parent_reflection # Reflection
#polymorphic? ⇒ Boolean (readonly)
[ GitHub ]
# File 'activerecord/lib/active_record/reflection.rb', line 831
def polymorphic? [:polymorphic] end
#type (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 582
attr_reader :type, :foreign_type, :extensions
#validate? ⇒ Boolean (readonly)
Returns whether or not the association should be validated as part of the parent's validation.
Unless you explicitly disable validation with validate: false, validation will take place when:
- you explicitly enable validation; validate: true
- you use autosave; autosave: true
- the association is a
has_manyassociation
# File 'activerecord/lib/active_record/reflection.rb', line 819
def validate? ![:validate].nil? ? [:validate] : ([:autosave] == true || collection?) end
Instance Method Details
#active_record_primary_key
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 709
def active_record_primary_key active_record_primary_key_definition.name end
#active_record_primary_key_definition
Same as #active_record_primary_key but returns an ::ActiveRecord::Key.
Only an explicit :primary_key is memoized; derived keys follow the
model's current schema.
# File 'activerecord/lib/active_record/reflection.rb', line 716
def active_record_primary_key_definition # :nodoc: if [:primary_key] @active_record_primary_key_definition ||= ActiveRecord::Key.for([:primary_key]) elsif active_record.has_query_constraints? || [:query_constraints] ActiveRecord::Key.for(active_record.query_constraints_list) else inferred_primary_key_definition(active_record) end end
#add_as_polymorphic_through(reflection, seed)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 843
def add_as_polymorphic_through(reflection, seed) seed + [PolymorphicReflection.new(self, reflection)] end
#add_as_source(seed)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 839
def add_as_source(seed) seed end
#add_as_through(seed)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 847
def add_as_through(seed) seed + [self] end
#association_class
# File 'activerecord/lib/active_record/reflection.rb', line 829
def association_class; raise NotImplementedError; end
#association_foreign_key
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 691
def association_foreign_key association_foreign_key_definition.name end
#association_foreign_key_definition
Same as #association_foreign_key but returns an ::ActiveRecord::Key.
# File 'activerecord/lib/active_record/reflection.rb', line 696
def association_foreign_key_definition # :nodoc: @association_foreign_key_definition ||= ActiveRecord::Key.for([:association_foreign_key] || class_name.foreign_key) end
#association_primary_key(klass = nil)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 700
def association_primary_key(klass = nil) association_primary_key_definition(klass).name end
#association_primary_key_definition(klass = nil)
Same as #association_primary_key but returns an ::ActiveRecord::Key.
# File 'activerecord/lib/active_record/reflection.rb', line 705
def association_primary_key_definition(klass = nil) # :nodoc: primary_key_definition(klass || self.klass) end
#association_route(origin_class: active_record, destination_class: nil)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 650
def association_route(origin_class: active_record, destination_class: nil) if origin_class.equal?(active_record) && (slot = @default_association_route) && (destination_class.nil? || destination_class.equal?(slot[1])) && current_default_association_route?(slot) return slot[3] end destination_class ||= klass unless polymorphic? if origin_class.equal?(active_record) && destination_class.equal?(default_destination_class) return default_association_route end # Schema contexts are replaced on reload, so key by both endpoints to # avoid reusing routes with outdated keys. by_destination = association_route_cache.fetch_or_store(origin_class.schema_context) { AssociationRoute::Cache.new } by_destination.fetch_or_store(destination_class&.schema_context) do resolve_association_route(origin_class, destination_class) end end
#association_route_cache (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 865
def association_route_cache AssociationRoute::Cache.for(self) end
#association_route_chain(origin_class: active_record, destination_class: nil)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 642
def association_route_chain(origin_class: active_record, destination_class: nil) [association_route(origin_class: origin_class, destination_class: destination_class)] end
#association_route_class (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 922
def association_route_class AssociationRoute::Reverse end
#association_route_constraints(_reference_class, _target_class) (private)
[ GitHub ]#association_route_target_key(_target_class) (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 918
def association_route_target_key(_target_class) active_record_primary_key_definition end
#automatic_inverse_of (private)
returns either nil or the inverse association name that it finds.
# File 'activerecord/lib/active_record/reflection.rb', line 957
def automatic_inverse_of if can_find_inverse_of_automatically?(self) inverse_name = ActiveSupport::Inflector.underscore([:as] || active_record.name.demodulize).to_sym begin reflection = klass._reflect_on_association(inverse_name) if !reflection && active_record.automatically_invert_plural_associations plural_inverse_name = ActiveSupport::Inflector.pluralize(inverse_name) reflection = klass._reflect_on_association(plural_inverse_name) end rescue NameError => error raise unless error.name.to_s == class_name # Give up: we couldn't compute the klass type so we won't be able # to find any associations either. reflection = false end if valid_inverse_reflection?(reflection) reflection.name end end end
#build_association_route(reference_class:, target_class:, fixed_values: {}) (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 926
def build_association_route(reference_class:, target_class:, fixed_values: {}) reference = Key::Mapping.new( reference_key: foreign_key_definition, target_key: association_route_target_key(target_class) ) constraints = association_route_constraints(reference_class, target_class) association_route_class.new( link: AssociationLink.for( reference: reference, constraints: constraints, fixed_values: fixed_values, reference_class: reference_class, target_class: target_class ) ) end
#can_find_inverse_of_automatically?(reflection, inverse_reflection = false) ⇒ Boolean (private)
Checks to see if the reflection doesn't have any options that prevent
us from being able to guess the inverse automatically. First, the
inverse_of option cannot be set to false. Second, we must
have has_many, has_one, belongs_to associations.
Third, we must not have options such as :foreign_key
which prevent us from correctly guessing the inverse association.
# File 'activerecord/lib/active_record/reflection.rb', line 999
def can_find_inverse_of_automatically?(reflection, inverse_reflection = false) reflection.[:inverse_of] != false && !reflection.[:through] && !reflection.[:foreign_key] && scope_allows_automatic_inverse_of?(reflection, inverse_reflection) end
#check_eager_loadable!
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 742
def check_eager_loadable! return unless scope unless scope.arity == 0 raise ArgumentError, <<-MSG.squish The association scope '#{name}' is instance dependent (the scope block takes an argument). Eager loading instance dependent scopes is not supported. MSG end end
#check_validity!
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 726
def check_validity! return if @validated check_validity_of_inverse! if !polymorphic? && (klass.composite_primary_key? || active_record.composite_primary_key?) if (has_one? || collection?) && active_record_primary_key_definition.length != foreign_key_definition.length raise CompositePrimaryKeyMismatchError.new(self) elsif belongs_to? && association_primary_key_definition.length != foreign_key_definition.length raise CompositePrimaryKeyMismatchError.new(self) end end @validated = true end
#clear_association_scope_cache(klass = self.klass)
Pass the concrete target class for polymorphic associations.
# File 'activerecord/lib/active_record/reflection.rb', line 769
def clear_association_scope_cache(klass = self.klass) # :nodoc: AssociationRoute::Cache.clear(self) @default_association_route = nil unless frozen? ActiveSupport::Ractors[@default_association_route_key] = nil klass.initialize_find_by_cache end
#collect_join_chain
A chain of reflections from this one back to the owner. For more see the explanation in
ThroughReflection.
# File 'activerecord/lib/active_record/reflection.rb', line 764
def collect_join_chain [self] end
#compute_class(name)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 558
def compute_class(name) if polymorphic? raise ArgumentError, "Polymorphic associations do not support computing the class." end begin klass = active_record.send(:compute_type, name) rescue NameError => error if error.name.match?(/(?:\A|::)#{name}\z/) = "Missing model class #{name} for the #{active_record}##{self.name} association." += " You can specify a different model class with the :class_name option." unless [:class_name] raise NameError.new(, name) else raise end end unless klass < ActiveRecord::Base raise ArgumentError, "The #{name} model class for the #{active_record}##{self.name} association is not an ActiveRecord::Base subclass." end klass end
#current_default_association_route?(slot) ⇒ Boolean (private)
Compares loaded contexts by identity: a context matching the slot's was loaded when the slot was filled, so this needn't load anything.
# File 'activerecord/lib/active_record/reflection.rb', line 901
def current_default_association_route?(slot) slot && slot[0].equal?(active_record.current_schema_context) && slot[2].equal?(slot[1]&.current_schema_context) end
#default_association_route (private)
Slots contain [origin context, destination class, destination context, route]. A slot resolved before the reflection is frozen is shared until a schema context changes; slots resolved later are stored per Ractor.
# File 'activerecord/lib/active_record/reflection.rb', line 876
def default_association_route slot = @default_association_route return slot[3] if current_default_association_route?(slot) if frozen? slot = ActiveSupport::Ractors[@default_association_route_key] return slot[3] if current_default_association_route?(slot) end destination_class = default_destination_class origin_context = active_record.schema_context destination_context = destination_class&.schema_context route = resolve_association_route(active_record, destination_class) slot = [origin_context, destination_class, destination_context, route].freeze if frozen? ActiveSupport::Ractors[@default_association_route_key] = slot else @default_association_route = slot end route end
#default_destination_class (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 869
def default_destination_class polymorphic? ? nil : klass end
#derive_class_name (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 1020
def derive_class_name class_name = name.to_s class_name = class_name.singularize if collection? class_name.camelize end
#derive_fk_query_constraints(foreign_key) (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 1038
def derive_fk_query_constraints(foreign_key) primary_query_constraints = active_record.query_constraints_list owner_pk = active_record.primary_key if primary_query_constraints.size > 2 raise ArgumentError, <<~MSG.squish The query constraints list on the `#{active_record}` model has more than 2 attributes. Active Record is unable to derive the query constraints for the association. You need to explicitly define the query constraints for this association. MSG end if !primary_query_constraints.include?(owner_pk) raise ArgumentError, <<~MSG.squish The query constraints on the `#{active_record}` model does not include the primary key so Active Record is unable to derive the foreign key constraints for the association. You need to explicitly define the query constraints for this association. MSG end return foreign_key if primary_query_constraints.include?(foreign_key) first_key, last_key = primary_query_constraints if first_key == owner_pk [foreign_key, last_key.to_s] elsif last_key == owner_pk [first_key.to_s, foreign_key] else raise ArgumentError, <<~MSG.squish Active Record couldn't correctly interpret the query constraints for the `#{active_record}` model. The query constraints on `#{active_record}` are `#{primary_query_constraints}` and the foreign key is `#{foreign_key}`. You need to explicitly set the query constraints for this association. MSG end end
#derive_foreign_key(infer_from_inverse_of: true) (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 1026
def derive_foreign_key(infer_from_inverse_of: true) if belongs_to? "#{name}_id" elsif [:as] "#{[:as]}_id" elsif [:inverse_of] && infer_from_inverse_of inverse_of.foreign_key(infer_from_inverse_of: false) else active_record.model_name.to_s.foreign_key end end
#derive_join_table (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 1078
def derive_join_table ModelSchema.derive_join_table_name active_record.table_name, klass.table_name end
#foreign_key(infer_from_inverse_of: true)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 670
def foreign_key(infer_from_inverse_of: true) foreign_key_definition(infer_from_inverse_of: infer_from_inverse_of).name end
#foreign_key_definition(infer_from_inverse_of: true)
Same as #foreign_key but returns an ::ActiveRecord::Key.
# File 'activerecord/lib/active_record/reflection.rb', line 675
def foreign_key_definition(infer_from_inverse_of: true) # :nodoc: @foreign_key_definition ||= if [:foreign_key] ActiveRecord::Key.for([:foreign_key]) elsif [:query_constraints] ActiveRecord::Key.for([:query_constraints]) else derived_fk = derive_foreign_key(infer_from_inverse_of: infer_from_inverse_of) if !derived_fk.is_a?(Array) && active_record.has_query_constraints? derived_fk = derive_fk_query_constraints(derived_fk) end ActiveRecord::Key.for(derived_fk) end end
#freeze
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 621
def freeze return self if frozen? check_validity! unless polymorphic? klass association_primary_key_definition if belongs_to? inverse_of inverse_which_updates_counter_cache end active_record_primary_key_definition association_foreign_key_definition counter_cache_column foreign_key_definition @scope = ActiveSupport::Ractors.try_shareable_proc(@scope) if @scope super end
#initialize_copy(other) (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 907
def initialize_copy(other) super @default_association_route = nil @default_association_route_key = :"active_record_default_association_route_#{object_id}" end
#inverse_name (private)
Attempts to find the inverse association name automatically.
If it cannot find a suitable inverse association name, it returns
nil.
# File 'activerecord/lib/active_record/reflection.rb', line 948
def inverse_name unless defined?(@inverse_name) @inverse_name = .fetch(:inverse_of) { automatic_inverse_of } end @inverse_name end
#join_table
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 646
def join_table @join_table ||= -([:join_table]&.to_s || derive_join_table) end
#macro
Returns the macro type.
has_many :clients returns :has_many
# File 'activerecord/lib/active_record/reflection.rb', line 801
def macro; raise NotImplementedError; end
#polymorphic_inverse_of(associated_class)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 788
def polymorphic_inverse_of(associated_class) if has_inverse? if inverse_relationship = associated_class._reflect_on_association([:inverse_of]) inverse_relationship else raise InverseOfAssociationNotFoundError.new(self, associated_class) end end end
#polymorphic_name
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 835
def polymorphic_name active_record.polymorphic_name end
#prepare_default_association_route
Resolves the default route ahead of the reflection being made shareable, so that every Ractor can read it from the frozen slot.
# File 'activerecord/lib/active_record/reflection.rb', line 857
def prepare_default_association_route # :nodoc: return unless @klass || polymorphic? return unless active_record.send(:schema_loaded?) && (polymorphic? || klass.send(:schema_loaded?)) default_association_route end
#resolve_association_route(origin_class, destination_class) (private)
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 913
def resolve_association_route(origin_class, destination_class) fixed_values = type ? { type => -origin_class.polymorphic_name } : {} build_association_route(reference_class: destination_class, target_class: origin_class, fixed_values: fixed_values) end
#scope_allows_automatic_inverse_of?(reflection, inverse_reflection) ⇒ Boolean (private)
Scopes on the potential inverse reflection prevent automatic
inverse_of, since the scope could exclude the owner record
we would inverse from. Scopes on the reflection itself allow for
automatic inverse_of as long as
config.active_record.automatic_scope_inversing is set to
{true} (the default for new applications).
# File 'activerecord/lib/active_record/reflection.rb', line 1012
def scope_allows_automatic_inverse_of?(reflection, inverse_reflection) if inverse_reflection !reflection.scope else !reflection.scope || reflection.klass.automatic_scope_inversing end end
#source_reflection
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 758
def source_reflection self end
#through_reflection
[ GitHub ]# File 'activerecord/lib/active_record/reflection.rb', line 754
def through_reflection nil end
#valid_inverse_reflection?(reflection) ⇒ Boolean (private)
Checks if the inverse reflection that is returned from the #automatic_inverse_of method is a valid reflection. We must make sure that the reflection's active_record name matches up with the current reflection's klass name.
# File 'activerecord/lib/active_record/reflection.rb', line 985
def valid_inverse_reflection?(reflection) reflection && reflection != self && foreign_key == reflection.foreign_key && klass <= reflection.active_record && can_find_inverse_of_automatically?(reflection, true) end