Class: YamlExporter::Builder
- Inherits:
-
Object
- Object
- YamlExporter::Builder
- Defined in:
- lib/yaml_exporter/builder.rb
Overview
Evaluates a yaml_structure do ... end block via instance_eval and emits
a Structure. All declaration-time argument validation happens here (or
inside the constructors of the Node classes it delegates to).
Accepts either a class or a callable that resolves to a class. The callable form lets node constructors defer AR reflection lookups until the inner block actually references the class (it doesn't, for attribute-only blocks) — this matters for anonymous ActiveRecord classes.
Instance Method Summary collapse
-
#attributes(*names) ⇒ Object
---- DSL ----------------------------------------------------------.
- #build ⇒ Object
-
#initialize(klass, &block) ⇒ Builder
constructor
A new instance of Builder.
- #many(name, find_by: nil, through: nil, positioned_by: nil, &block) ⇒ Object
- #one(name, find_by: nil, of: nil, &block) ⇒ Object
Constructor Details
#initialize(klass, &block) ⇒ Builder
Returns a new instance of Builder.
14 15 16 17 18 |
# File 'lib/yaml_exporter/builder.rb', line 14 def initialize(klass, &block) @klass_resolver = klass.respond_to?(:call) ? klass : -> { klass } @nodes = [] instance_eval(&block) if block end |
Instance Method Details
#attributes(*names) ⇒ Object
---- DSL ----------------------------------------------------------
26 27 28 |
# File 'lib/yaml_exporter/builder.rb', line 26 def attributes(*names) names.each { |n| @nodes << Nodes::Attribute.new(name: n, owner_class: @klass_resolver) } end |
#build ⇒ Object
20 21 22 |
# File 'lib/yaml_exporter/builder.rb', line 20 def build Structure.new(klass: @klass_resolver, nodes: @nodes.freeze) end |
#many(name, find_by: nil, through: nil, positioned_by: nil, &block) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/yaml_exporter/builder.rb', line 52 def many(name, find_by: nil, through: nil, positioned_by: nil, &block) if through unless find_by raise ArgumentError, "`many #{name.inspect}`: through: requires find_by: to resolve the target." end # A block is optional: with one, its attributes describe the join row; # without one, the association is a bare reference list (and # positioned_by:, when given, derives the join's position column from # the YAML order). The join row itself is always managed by the DSL. @nodes << Nodes::ManyThrough.new( name: name, owner_class: klass, through: through, find_by: find_by, positioned_by: positioned_by, &block ) elsif positioned_by && !block raise ArgumentError, "`many #{name.inspect}`: positioned_by: requires a block — the column lives on the owned record." elsif block && find_by @nodes << Nodes::ManyFindBy.new( name: name, owner_class: klass, find_by: find_by, positioned_by: positioned_by, &block ) elsif block @nodes << Nodes::ManyPositional.new( name: name, owner_class: klass, positioned_by: positioned_by, &block ) elsif find_by @nodes << Nodes::ManyReference.new(name: name, owner_class: klass, find_by: find_by) else raise ArgumentError, "`many #{name.inspect}`: pass either find_by: (reference list), a block (owned), " \ 'or both / through: + find_by: + block.' end end |
#one(name, find_by: nil, of: nil, &block) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/yaml_exporter/builder.rb', line 30 def one(name, find_by: nil, of: nil, &block) if block && find_by raise ArgumentError, "`one #{name.inspect}`: cannot combine a block (owned) with find_by: (reference). Pick one." end if of && !find_by raise ArgumentError, "`one #{name.inspect}`: of: requires find_by:." end if block @nodes << Nodes::OneOwned.new(name: name, owner_class: klass, &block) elsif find_by && of @nodes << Nodes::OneReferenceOf.new(name: name, owner_class: klass, find_by: find_by, of: of) elsif find_by @nodes << Nodes::OneReference.new(name: name, owner_class: klass, find_by: find_by) else raise ArgumentError, "`one #{name.inspect}`: must pass either find_by: (reference) or a block (owned)." end end |