Class: YamlExporter::Nodes::ManyFindBy

Inherits:
ManyBase
  • Object
show all
Defined in:
lib/yaml_exporter/nodes/many_find_by.rb

Overview

many :assoc, find_by: :column do ... end — identity is the find_by column value. Existing rows are matched by key; duplicates in the incoming YAML raise DuplicateKeyError.

Instance Attribute Summary

Attributes inherited from ManyBase

#find_by, #name, #owner_class, #positioned_by, #sub_structure

Instance Method Summary collapse

Methods inherited from ManyBase

#build_child, #current_entries, #destroy_missing, #entry_class, #extra_entry_schema, #initialize, #phase, #schema_fragment, #sort_for_export, #target_class, #yaml_keys

Constructor Details

This class inherits a constructor from YamlExporter::Nodes::ManyBase

Instance Method Details

#default_export_order(records) ⇒ Object



19
20
21
# File 'lib/yaml_exporter/nodes/many_find_by.rb', line 19

def default_export_order(records)
  records.sort_by { |r| r.public_send(@find_by).to_s }
end

#export(parent, exporter:) ⇒ Object

Re-emit the find_by column first in each entry so round-trips stay stable (and readers see the discriminator up top).



33
34
35
36
37
38
39
40
41
# File 'lib/yaml_exporter/nodes/many_find_by.rb', line 33

def export(parent, exporter:)
  records = sort_for_export(Array(parent.public_send(@name)))
  list = records.map do |child|
    hash = { @find_by.to_s => child.public_send(@find_by) }
    hash.merge!(exporter.build_hash(child, @sub_structure))
    hash
  end
  [@name.to_s, list]
end

#extra_entry_keysObject



23
24
25
# File 'lib/yaml_exporter/nodes/many_find_by.rb', line 23

def extra_entry_keys
  [@find_by.to_s]
end

#find_or_build_child(parent, entry, _index, existing:) ⇒ Object



9
10
11
12
13
14
15
16
17
# File 'lib/yaml_exporter/nodes/many_find_by.rb', line 9

def find_or_build_child(parent, entry, _index, existing:)
  key = entry[@find_by.to_s]
  match = existing.find { |c| c.public_send(@find_by) == key }
  return match if match

  build_child(parent).tap do |child|
    child.public_send("#{@find_by}=", key)
  end
end

#import(parent, data, path:, importer:) ⇒ Object

Wrap the shared import to insert duplicate detection up front.



63
64
65
66
67
# File 'lib/yaml_exporter/nodes/many_find_by.rb', line 63

def import(parent, data, path:, importer:)
  entries = data.key?(@name.to_s) ? data[@name.to_s] : nil
  reject_duplicates!(entries, path) if entries.is_a?(Array)
  super
end