Class: YamlExporter::Nodes::ManyReference
- Inherits:
-
Object
- Object
- YamlExporter::Nodes::ManyReference
- Includes:
- OfResolution
- Defined in:
- lib/yaml_exporter/nodes/many_reference.rb
Overview
many :assoc, find_by: :column — standalone reference list (HABTM or
has_many). No block, no entry attributes: each YAML string resolves to
an existing target record via find_by. Target records are never
created or mutated; only the association is updated.
With of: the value is resolved indirectly through a 1:[0,1]
association on the target (see OfResolution), so the YAML lists the
find_by value of a related model (e.g. the user slug behind each
target) rather than a column on the target itself.
Phase: :post_save (join rows / FK need parent.id).
Instance Attribute Summary collapse
-
#find_by ⇒ Object
readonly
Returns the value of attribute find_by.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#of ⇒ Object
readonly
Returns the value of attribute of.
-
#owner_class ⇒ Object
readonly
Returns the value of attribute owner_class.
Instance Method Summary collapse
- #export(record, exporter:) ⇒ Object
- #import(record, data, path:, importer:) ⇒ Object
-
#initialize(name:, owner_class:, find_by:, of: nil) ⇒ ManyReference
constructor
A new instance of ManyReference.
- #phase ⇒ Object
- #schema_fragment ⇒ Object
- #target_class ⇒ Object
- #yaml_keys ⇒ Object
Methods included from OfResolution
#find_target_via, #of_class, #of_reflection, #of_value_for, #resolve_target_by_of, #singular_of_association?, #validate_of_reflection!
Constructor Details
#initialize(name:, owner_class:, find_by:, of: nil) ⇒ ManyReference
Returns a new instance of ManyReference.
21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 21 def initialize(name:, owner_class:, find_by:, of: nil) @name = name.to_sym @owner_class = owner_class @find_by = find_by.to_sym @of = of&.to_sym reflection = owner_class.reflect_on_association(@name) unless reflection raise ArgumentError, "`many #{name.inspect}`: #{owner_class} has no association `#{name}`" end validate_of_reflection!("many #{name.inspect}") if @of end |
Instance Attribute Details
#find_by ⇒ Object (readonly)
Returns the value of attribute find_by.
19 20 21 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 19 def find_by @find_by end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
19 20 21 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 19 def name @name end |
#of ⇒ Object (readonly)
Returns the value of attribute of.
19 20 21 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 19 def of @of end |
#owner_class ⇒ Object (readonly)
Returns the value of attribute owner_class.
19 20 21 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 19 def owner_class @owner_class end |
Instance Method Details
#export(record, exporter:) ⇒ Object
64 65 66 67 68 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 64 def export(record, exporter:) targets = Array(record.public_send(@name)) keys = targets.map { |t| key_for(t) }.compact.sort [@name.to_s, keys] end |
#import(record, data, path:, importer:) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 47 def import(record, data, path:, importer:) raw = data.key?(@name.to_s) ? data[@name.to_s] : nil values = Array(raw) unless values.all? { |v| v.is_a?(String) || v.is_a?(Symbol) || v.is_a?(Numeric) } raise UnknownAttributeError, "#{describe_path(path)}: expected a list of #{@find_by} values, got #{raw.inspect}" end targets = values.map do |value| resolve_target(value) || (raise ActiveRecord::RecordNotFound, (value)) end record.public_send("#{@name}=", targets) end |
#phase ⇒ Object
35 36 37 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 35 def phase :post_save end |
#schema_fragment ⇒ Object
70 71 72 73 74 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 70 def schema_fragment key_class = @of ? of_class : target_class item_type = TypeInference.schema_type_for(key_class, @find_by) { @name => { type: 'array', items: { type: item_type } } } end |
#target_class ⇒ Object
43 44 45 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 43 def target_class @target_class ||= @owner_class.reflect_on_association(@name).klass end |
#yaml_keys ⇒ Object
39 40 41 |
# File 'lib/yaml_exporter/nodes/many_reference.rb', line 39 def yaml_keys [@name.to_s] end |