Class: ActiveRecord::AssociationRoute
Do not use. This class is for internal use only.
| Relationships & Source Files | |
| Namespace Children | |
|
Classes:
| |
| Inherits: | Object |
| Defined in: | activerecord/lib/active_record/association_route.rb |
Overview
An association's resolved connection from a concrete origin class to its destination.
Constant Summary
-
EMPTY_FIXED_VALUES =
private
# File 'activerecord/lib/active_record/association_route.rb', line 171{}.freeze -
EMPTY_KEY_PAIRS =
private
# File 'activerecord/lib/active_record/association_route.rb', line 172[].freeze -
STRING_NORMALIZER =
private
# File 'activerecord/lib/active_record/association_route.rb', line 173ActiveSupport::Ractors.shareable_lambda { |value| value&.to_s }.freeze
Class Method Summary
- .new(link:) ⇒ AssociationRoute constructor
Instance Attribute Summary
-
#_destination_key
readonly
Physical (alias-resolved) counterparts of the above.
-
#_origin_key
readonly
Physical (alias-resolved) counterparts of the above.
-
#_reference_destination_key
readonly
Physical (alias-resolved) counterparts of the above.
-
#_reference_origin_key
readonly
Physical (alias-resolved) counterparts of the above.
- #destination_key readonly
- #hash readonly
- #link readonly
- #origin_key readonly
- #predicate_accepts_bare_id? ⇒ Boolean readonly
- #reference_destination_key readonly
- #reference_origin_key readonly
Instance Method Summary
- #==(other) (also: #eql?)
- #clear_reference(reference_record)
- #destination_fixed_values
- #each_constraint(&block)
- #each_match(&block)
- #each_matching_origin(origins, destination)
- #each_reference(&block)
-
#eql?(other)
Alias for #==.
- #key_values_match?(origin, destination) ⇒ Boolean
-
#match_normalizers(origin_class:, destination_class:)
Per-column conversions for comparing origin and destination key values.
- #origin_fixed_values
- #origin_reference_complete?(origin) ⇒ Boolean
- #reference_needs_update?(origin, destination) ⇒ Boolean
- #write(origin, destination, force: true)
- #build_match_normalizers(origin_class, destination_class) private
- #initialize_keys private
- #normalizers_for_types(origin_type, destination_type) private
- #pairs_for(origin_key, destination_key) private
Constructor Details
.new(link:) ⇒ AssociationRoute
# File 'activerecord/lib/active_record/association_route.rb', line 196
def initialize(link:) @link = link initialize_keys @key_pairs = pairs_for(origin_key, destination_key) @reference_pairs = if link.constraints.empty? @key_pairs else pairs_for(reference_origin_key, reference_destination_key) end @hash = [self.class, link].hash freeze end
Instance Attribute Details
#_destination_key (readonly)
Physical (alias-resolved) counterparts of the above.
# File 'activerecord/lib/active_record/association_route.rb', line 219
attr_reader :_origin_key, :_destination_key, :_reference_origin_key, :_reference_destination_key
#_origin_key (readonly)
Physical (alias-resolved) counterparts of the above.
# File 'activerecord/lib/active_record/association_route.rb', line 219
attr_reader :_origin_key, :_destination_key, :_reference_origin_key, :_reference_destination_key
#_reference_destination_key (readonly)
Physical (alias-resolved) counterparts of the above.
# File 'activerecord/lib/active_record/association_route.rb', line 219
attr_reader :_origin_key, :_destination_key, :_reference_origin_key, :_reference_destination_key
#_reference_origin_key (readonly)
Physical (alias-resolved) counterparts of the above.
# File 'activerecord/lib/active_record/association_route.rb', line 219
attr_reader :_origin_key, :_destination_key, :_reference_origin_key, :_reference_destination_key
#destination_key (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 216
attr_reader :origin_key, :destination_key, :reference_origin_key, :reference_destination_key
#hash (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 214
attr_reader :hash
#link (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 194
attr_reader :link
#origin_key (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 216
attr_reader :origin_key, :destination_key, :reference_origin_key, :reference_destination_key
#predicate_accepts_bare_id? ⇒ Boolean (readonly)
[ GitHub ]
# File 'activerecord/lib/active_record/association_route.rb', line 221
def !origin_key.composite? && !reference_origin_key.composite? end
#reference_destination_key (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 216
attr_reader :origin_key, :destination_key, :reference_origin_key, :reference_destination_key
#reference_origin_key (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 216
attr_reader :origin_key, :destination_key, :reference_origin_key, :reference_destination_key
Instance Method Details
#==(other) Also known as: #eql?
[ GitHub ]#build_match_normalizers(origin_class, destination_class) (private)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 307
def build_match_normalizers(origin_class, destination_class) origin_normalizers = destination_normalizers = nil each_match.with_index do |(origin_column, destination_column), index| origin_type = origin_class.type_for_attribute(origin_column) destination_type = destination_class.type_for_attribute(destination_column) origin_normalizer, destination_normalizer = normalizers_for_types(origin_type, destination_type) if origin_normalizer (origin_normalizers ||= Array.new(@key_pairs.length))[index] = origin_normalizer end if destination_normalizer (destination_normalizers ||= Array.new(@key_pairs.length))[index] = destination_normalizer end end [origin_normalizers&.freeze, destination_normalizers&.freeze].freeze end
#clear_reference(reference_record)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 290
def clear_reference(reference_record, **) @link.clear_reference(reference_record, **) end
#destination_fixed_values
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 282
def destination_fixed_values EMPTY_FIXED_VALUES end
#each_constraint(&block)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 274
def each_constraint(&block) @constraint_pairs.each(&block) end
#each_match(&block)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 225
def each_match(&block) @key_pairs.each(&block) end
#each_matching_origin(origins, destination)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 246
def each_matching_origin(origins, destination) return enum_for(__method__, origins, destination) unless block_given? # The destination's conversion depends on the owner's attribute types, so # cache its converted value separately for each owner class. comparisons_by_class = {} origins.each do |origin| origin_normalizers, destination_value = comparisons_by_class[origin.class] ||= begin origin_normalizers, destination_normalizers = match_normalizers(origin_class: origin.class, destination_class: destination.class) [origin_normalizers, destination_key.value_of(destination, destination_normalizers)] end yield origin if origin_key.value_of(origin, origin_normalizers) == destination_value end end
#each_reference(&block)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 270
def each_reference(&block) @reference_pairs.each(&block) end
#eql?(other)
Alias for #==.
# File 'activerecord/lib/active_record/association_route.rb', line 212
alias_method :eql?, :==
#initialize_keys (private)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 295
def initialize_keys @origin_key = link.match&.reference_key @destination_key = link.match&.target_key @reference_origin_key = link.reference_key @reference_destination_key = link.reference&.target_key @_origin_key = link._match_reference_key @_destination_key = link._match_target_key @_reference_origin_key = link._reference_key @_reference_destination_key = link._target_key @constraint_pairs = link.constraints.empty? ? EMPTY_KEY_PAIRS : pairs_for(link.constraints.reference_key, link.constraints.target_key) end
#key_values_match?(origin, destination) ⇒ Boolean
# File 'activerecord/lib/active_record/association_route.rb', line 241
def key_values_match?(origin, destination) origin_normalizers, destination_normalizers = match_normalizers(origin_class: origin.class, destination_class: destination.class) _origin_key._value_of(origin, origin_normalizers) == _destination_key._value_of(destination, destination_normalizers) end
#match_normalizers(origin_class:, destination_class:)
Per-column conversions for comparing origin and destination key values. A nil list or entry leaves the corresponding values unchanged.
# File 'activerecord/lib/active_record/association_route.rb', line 231
def match_normalizers(origin_class:, destination_class:) # Schema contexts are replaced on reload, so key by them to avoid # reusing conversions computed from outdated attribute types. cache = Cache.for(self) by_destination = cache.fetch_or_store(origin_class.schema_context) { Cache.new } by_destination.fetch_or_store(destination_class.schema_context) do build_match_normalizers(origin_class, destination_class) end end
#normalizers_for_types(origin_type, destination_type) (private)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 324
def normalizers_for_types(origin_type, destination_type) unless origin_type.type == destination_type.type [STRING_NORMALIZER, STRING_NORMALIZER] end end
#origin_fixed_values
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 278
def origin_fixed_values @link.fixed_values end
#origin_reference_complete?(origin) ⇒ Boolean
# File 'activerecord/lib/active_record/association_route.rb', line 262
def origin_reference_complete?(origin) _reference_origin_key.all? { |column| !origin._read_attr(column).nil? } end
#pairs_for(origin_key, destination_key) (private)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 330
def pairs_for(origin_key, destination_key) origin_key.zip(destination_key).map!(&:freeze).freeze if origin_key && destination_key end
#reference_needs_update?(origin, destination) ⇒ Boolean
# File 'activerecord/lib/active_record/association_route.rb', line 266
def reference_needs_update?(origin, destination) @link.reference_needs_update?(origin, destination) end
#write(origin, destination, force: true)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 286
def write(origin, destination, force: true) @link.write_reference(origin, destination, force: force) end