Module: Plutonium::Wizard::FieldImporter
- Defined in:
- lib/plutonium/wizard/field_importer.rb
Overview
Resolves a step's using: option (§2.4) — importing a field surface from a
model (ActiveRecord class) instead of re-declaring it.
using: targets a model only. A Plutonium::Resource::Definition carries no
link to its model (it's an empty class the controller binds at request time),
so the only reliable direction is model → definition: the importer
auto-resolves "#{Model}Definition" to overlay input styling, best-effort.
The imported surface is:
- **attribute_schema** ({name => type}) — the field universe is
`Model.attribute_names` (filtered by selectors); types are
`Model.attribute_types[name].type`.
- **inputs** ({name => {options:, block:}}) — overlaid from the resolved
`<Model>Definition`'s `field`/`input` config (`as:`, options, labels),
sliced to the imported names. No definition → empty input config.
- **form_layout** — the resolved `<Model>Definition`'s `defined_form_layout`,
filtered to the imported fields, **plus a trailing ungrouped section** for
imported fields not named in any explicit section (skipped when
`layout: false`).
- **validate_fn** — runs a transient `Model.new(slice).valid?` and keeps
errors only on the imported fields **plus `:base`** (skipped when
`validate: false`).
Validation is run-and-filtered rather than cloned: AR validators can't be
cloned cleanly. Filtering to imported fields + :base is what prevents a
partial model reporting presence errors for columns this step never collects.
Defined Under Namespace
Classes: Spec
Constant Summary collapse
- FORM_VALIDATOR_KINDS =
The validator kinds the form pipeline reads for field metadata (required marker, maxlength/minlength, min/max, pattern, auto-choices). Other kinds (uniqueness, custom EachValidators) carry no form meaning, so we skip them — and replaying a custom kind through
validateswould raise. %i[presence length numericality format inclusion].freeze
Class Method Summary collapse
Class Method Details
.resolve(using:, opts:) ⇒ Spec
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 |
# File 'lib/plutonium/wizard/field_importer.rb', line 52 def resolve(using:, opts:) model = model!(using) opts ||= {} only = normalize(opts[:fields] || opts[:only]) except = normalize(opts[:except]) || [] do_validate = opts.fetch(:validate, true) do_layout = opts.fetch(:layout, true) context = opts[:validation_context] names = select(model.attribute_names.map(&:to_sym), only:, except:) definition = "#{model.name}Definition".safe_constantize schema = names.index_with { |n| record_type(model, n) } validate_fn = build_validate(do_validate) do |slice| record = model.new(string_slice(slice, names)) run_and_filter(record, names, context) end Spec.new( attribute_schema: schema, inputs: inputs_for(definition, names), form_layout: do_layout ? layout_for(definition, names) : nil, validate_fn:, form_validators: form_validators_for(model, names) ) end |