Class: YamlExporter::Importer
- Inherits:
-
Object
- Object
- YamlExporter::Importer
- Defined in:
- lib/yaml_exporter/importer.rb
Overview
Drives the import of a YAML document into a tree of ActiveRecord records.
Works in a single transaction on the root record's class. For every record it touches (root + any owned child) it runs two phases:
1. pre_save — nodes that mutate columns on *this* record
(Attribute, OneReference).
2. save! — the record is now persisted and has an id.
3. post_save — nodes that need parent.id to do their work
(OneOwned, ManyPositional, ManyFindBy,
ManyReference, ManyThrough).
Each node is responsible for its own persistence; this class just orchestrates phases and validates unknown keys.
Instance Method Summary collapse
-
#apply(record, structure, data, path:, extra_keys: []) ⇒ Object
Called recursively by nodes that own child records (OneOwned, ManyBase flavors) once they've built or found the child row.
- #import(yaml_string) ⇒ Object
-
#initialize(record, structure) ⇒ Importer
constructor
A new instance of Importer.
Constructor Details
#initialize(record, structure) ⇒ Importer
Returns a new instance of Importer.
19 20 21 22 |
# File 'lib/yaml_exporter/importer.rb', line 19 def initialize(record, structure) @root_record = record @root_structure = structure end |
Instance Method Details
#apply(record, structure, data, path:, extra_keys: []) ⇒ Object
Called recursively by nodes that own child records (OneOwned, ManyBase flavors) once they've built or found the child row.
extra_keys lets the caller (typically a many node) declare keys
that belong to it, not to structure. Example: find_by: :slug
means slug: is legal at the entry level but isn't a declared
Attribute on the child — it's the discriminator the parent node
consumes. The child's own Attribute setters never see it because
no Attribute node declares it; it simply passes validation.
41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/yaml_exporter/importer.rb', line 41 def apply(record, structure, data, path:, extra_keys: []) data = {} if data.nil? unless data.is_a?(Hash) raise UnknownAttributeError, "#{describe_path(path)}: expected a mapping, got #{data.class}" end validate_keys!(structure, data, path: path, extra_keys: extra_keys) pre, post = structure.nodes.partition { |n| n.phase == :pre_save } pre.each { |n| n.import(record, data, path: path, importer: self) } record.save! post.each { |n| n.import(record, data, path: path, importer: self) } end |
#import(yaml_string) ⇒ Object
24 25 26 27 28 29 30 |
# File 'lib/yaml_exporter/importer.rb', line 24 def import(yaml_string) @root_record.class.transaction do data = parse(yaml_string) apply(@root_record, @root_structure, data, path: '') end @root_record end |