Class: ActiveRecord::AssociationLink
| Relationships & Source Files | |
| Namespace Children | |
|
Classes:
| |
| Inherits: | Object |
| Defined in: | activerecord/lib/active_record/association_route.rb |
Overview
An association's writable foreign-key reference and query-only constraints from the perspective of the record that holds the foreign key.
Constant Summary
-
EMPTY_FIXED_VALUES =
private
# File 'activerecord/lib/active_record/association_route.rb', line 10{}.freeze
Class Method Summary
Instance Attribute Summary
-
#_fixed_values
readonly
Physical (alias-resolved) counterparts of the above.
-
#_match_reference_key
readonly
Physical (alias-resolved) counterparts of the above.
-
#_match_target_key
readonly
Physical (alias-resolved) counterparts of the above.
-
#_reference_key
readonly
Physical (alias-resolved) counterparts of the above.
-
#_target_key
readonly
Physical (alias-resolved) counterparts of the above.
- #constraints readonly
-
#fixed_values
readonly
Attributeswritten alongside the foreign key, such as a polymorphic type. - #hash readonly
- #match readonly
- #reference readonly
- #reference_key readonly
Instance Method Summary
- #==(other) (also: #eql?)
- #clear_reference(reference_record, preserve: nil, fixed_values: true, force: true)
-
#eql?(other)
Alias for #==.
- #reference_needs_update?(reference_record, target_record) ⇒ Boolean
- #reference_values(target_record)
- #write_reference(reference_record, target_record, force: true)
- #each_reference_key_value(target_record) private
- #each_reference_value(target_record) private
- #resolve_aliases(key, owner) private
- #resolve_fixed_values(fixed_values, owner) private
- #writes_mapped_id?(reference_class) ⇒ Boolean private
Constructor Details
.new(reference: nil, reference_key: reference&.reference_key, constraints: Key::Mapping.empty, fixed_values: EMPTY_FIXED_VALUES, reference_class: nil, target_class: nil) ⇒ AssociationLink
# File 'activerecord/lib/active_record/association_route.rb', line 30
def initialize(reference: nil, reference_key: reference&.reference_key, constraints: Key::Mapping.empty, fixed_values: EMPTY_FIXED_VALUES, reference_class: nil, target_class: nil) @reference = reference @reference_key = reference_key @constraints = constraints @fixed_values = fixed_values.freeze @match = (constraints + reference).normalize if reference @_reference_key = resolve_aliases(reference_key, reference_class) @_target_key = resolve_aliases(reference&.target_key, target_class) @_match_reference_key = resolve_aliases(@match&.reference_key, reference_class) @_match_target_key = resolve_aliases(@match&.target_key, target_class) @_fixed_values = resolve_fixed_values(@fixed_values, reference_class) @hash = [self.class, reference, reference_key, constraints, @fixed_values, @_reference_key, @_target_key, @_match_reference_key, @_match_target_key].hash freeze end
Class Method Details
.for(reference_class: nil, **options)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 13
def self.for(reference_class: nil, **) link = new(reference_class: reference_class, **) if link.send(:writes_mapped_id?, reference_class) DeprecatedIdWriter.new(reference_class: reference_class, **) else link end end
Instance Attribute Details
#_fixed_values (readonly)
Physical (alias-resolved) counterparts of the above.
# File 'activerecord/lib/active_record/association_route.rb', line 28
attr_reader :_reference_key, :_target_key, :_match_reference_key, :_match_target_key, :_fixed_values
#_match_reference_key (readonly)
Physical (alias-resolved) counterparts of the above.
# File 'activerecord/lib/active_record/association_route.rb', line 28
attr_reader :_reference_key, :_target_key, :_match_reference_key, :_match_target_key, :_fixed_values
#_match_target_key (readonly)
Physical (alias-resolved) counterparts of the above.
# File 'activerecord/lib/active_record/association_route.rb', line 28
attr_reader :_reference_key, :_target_key, :_match_reference_key, :_match_target_key, :_fixed_values
#_reference_key (readonly)
Physical (alias-resolved) counterparts of the above.
# File 'activerecord/lib/active_record/association_route.rb', line 28
attr_reader :_reference_key, :_target_key, :_match_reference_key, :_match_target_key, :_fixed_values
#_target_key (readonly)
Physical (alias-resolved) counterparts of the above.
# File 'activerecord/lib/active_record/association_route.rb', line 28
attr_reader :_reference_key, :_target_key, :_match_reference_key, :_match_target_key, :_fixed_values
#constraints (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 22
attr_reader :reference, :reference_key, :constraints, :match
#fixed_values (readonly)
Attributes written alongside the foreign key, such as a polymorphic type.
# File 'activerecord/lib/active_record/association_route.rb', line 25
attr_reader :fixed_values
#hash (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 61
attr_reader :hash
#match (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 22
attr_reader :reference, :reference_key, :constraints, :match
#reference (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 22
attr_reader :reference, :reference_key, :constraints, :match
#reference_key (readonly)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 22
attr_reader :reference, :reference_key, :constraints, :match
Instance Method Details
#==(other) Also known as: #eql?
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 48
def ==(other) other.instance_of?(self.class) && reference == other.reference && reference_key == other.reference_key && constraints == other.constraints && fixed_values == other.fixed_values && _reference_key == other._reference_key && _target_key == other._target_key && _match_reference_key == other._match_reference_key && _match_target_key == other._match_target_key end
#clear_reference(reference_record, preserve: nil, fixed_values: true, force: true)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 94
def clear_reference(reference_record, preserve: nil, fixed_values: true, force: true) _reference_key.each do |column| next if preserve&.include?(column) reference_record._write_attribute(column, nil) end return unless fixed_values _fixed_values.each_key do |column| next if !force && reference_record._read_attr(column).nil? reference_record._write_attribute(column, nil) end end
#each_reference_key_value(target_record) (private)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 132
def each_reference_key_value(target_record) return enum_for(__method__, target_record) unless block_given? target_columns = reference.target_key.columns if target_record reference_key.each_with_index do |column, index| yield column, target_record&.read_attr(target_columns[index]) end end
#each_reference_value(target_record) (private)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 125
def each_reference_value(target_record, &) return enum_for(__method__, target_record) unless block_given? each_reference_key_value(target_record, &) fixed_values.each(&) end
#eql?(other)
Alias for #==.
# File 'activerecord/lib/active_record/association_route.rb', line 59
alias_method :eql?, :==
#reference_needs_update?(reference_record, target_record) ⇒ Boolean
# File 'activerecord/lib/active_record/association_route.rb', line 67
def reference_needs_update?(reference_record, target_record) if _reference_key.all? { |column| reference_record._has_attribute?(column) } target_columns = _target_key.columns if target_record _reference_key.each_with_index do |column, index| return true if reference_record._read_attr(column) != target_record&._read_attr(target_columns[index]) end end _fixed_values.any? do |column, value| reference_record._has_attribute?(column) && reference_record._read_attr(column) != value end end
#reference_values(target_record)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 63
def reference_values(target_record) each_reference_value(target_record).to_h end
#resolve_aliases(key, owner) (private)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 116
def resolve_aliases(key, owner) owner ? key&.resolve_aliases(owner) : key end
#resolve_fixed_values(fixed_values, owner) (private)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 120
def resolve_fixed_values(fixed_values, owner) return fixed_values if owner.nil? || fixed_values.none? { |column, _| owner.resolve_alias(column) != column } fixed_values.to_h { |column, value| [-owner.resolve_alias(column), value] }.freeze end
#write_reference(reference_record, target_record, force: true)
[ GitHub ]# File 'activerecord/lib/active_record/association_route.rb', line 80
def write_reference(reference_record, target_record, force: true) target_columns = _target_key.columns if target_record _reference_key.each_with_index do |column, index| value = target_record&._read_attr(target_columns[index]) next if !force && reference_record._read_attr(column) == value reference_record._write_attribute(column, value) end _fixed_values.each do |column, value| next if !force && reference_record._read_attr(column) == value reference_record._write_attribute(column, value) end unless _fixed_values.empty? end
#writes_mapped_id?(reference_class) ⇒ Boolean (private)
# File 'activerecord/lib/active_record/association_route.rb', line 108
def writes_mapped_id?(reference_class) return false unless reference_class primary_key = reference_class.primary_key primary_key && primary_key != "id" && !reference_class.composite_primary_key? && (_reference_key.include?("id") || _fixed_values.key?("id")) end