class Formwandler::Form

Attributes

model_save_order[R]
controller[R]
models[R]

Public Class Methods

attribute_accessor(name) click to toggle source
# File lib/formwandler/form.rb, line 39
def attribute_accessor(name)
  define_method "#{name}=" do |value|
    field(name).value = value
  end

  define_method name do
    field(name).value
  end
end
field(name, opts = {}, &block) click to toggle source
# File lib/formwandler/form.rb, line 31
def field(name, opts = {}, &block)
  field_definition = field_definitions[name] ||= FieldDefinition.new(name)
  field_definition.configure(opts)
  field_definition.instance_exec(&block) if block_given?

  attribute_accessor(name)
end
field_definitions() click to toggle source
# File lib/formwandler/form.rb, line 27
def field_definitions
  @field_definitions ||= {}
end
human_attribute_name(attr, options = {}) click to toggle source
Calls superclass method
# File lib/formwandler/form.rb, line 17
def human_attribute_name(attr, options = {})
  field_definition = @field_definitions.fetch(attr) { nil }
  if options[:default].nil? && field_definition && field_definition.model_class
    not_found = '__formwandler_not_found__'
    model_translation = field_definition.model_class.human_attribute_name(field_definition.source, default: not_found)
    options[:default] = model_translation unless model_translation == not_found
  end
  super(attr, options)
end
model_name() click to toggle source
# File lib/formwandler/form.rb, line 13
def model_name
  ActiveModel::Name.new(self, nil, name.chomp('Form').underscore)
end
new(models: {}, controller:) click to toggle source
# File lib/formwandler/form.rb, line 58
def initialize(models: {}, controller:)
  @models = models.symbolize_keys
  @controller = controller

  initialize_fields
  initialize_models
  assign_defaults
  assign_params
end
save_order(*model_names) click to toggle source
# File lib/formwandler/form.rb, line 49
def save_order(*model_names)
  @model_save_order = model_names
end

Public Instance Methods

field(name) click to toggle source
# File lib/formwandler/form.rb, line 76
def field(name)
  @fields.fetch(name)
end
fields(*names) click to toggle source
# File lib/formwandler/form.rb, line 80
def fields(*names)
  if names.any?
    @fields.fetch_values(*names)
  else
    @fields.values
  end
end
fields_for_model(model) click to toggle source
# File lib/formwandler/form.rb, line 88
def fields_for_model(model)
  fields.select { |field| field.model == model }
end
persisted?() click to toggle source
# File lib/formwandler/form.rb, line 68
def persisted?
  models.values.first&.persisted? || false
end
submit() click to toggle source
# File lib/formwandler/form.rb, line 98
def submit
  if valid?
    ActiveRecord::Base.transaction do
      save_models!
    end
    load_results
  else
    false
  end
end
to_param() click to toggle source
# File lib/formwandler/form.rb, line 72
def to_param
  models.values.first.to_param
end
valid?() click to toggle source
Calls superclass method
# File lib/formwandler/form.rb, line 92
def valid?
  form_valid = super
  models_valid = models_valid?
  form_valid && models_valid
end

Private Instance Methods

assign_defaults() click to toggle source
# File lib/formwandler/form.rb, line 114
def assign_defaults
  fields.each do |field|
    next unless field.default?
    send("#{field.name}=", field.default) if send(field.name).nil?
  end
end
assign_params() click to toggle source
# File lib/formwandler/form.rb, line 121
def assign_params
  return unless form_params?
  assign_attributes permitted_params
end
delocalizations() click to toggle source
# File lib/formwandler/form.rb, line 165
def delocalizations
  fields.reduce({}) do |memo, field|
    memo[field.name] = field.delocalize
    memo
  end.compact
end
form_params?() click to toggle source
# File lib/formwandler/form.rb, line 151
def form_params?
  controller.params.fetch(model_name.param_key, {}).to_unsafe_h.any?
end
initialize_fields() click to toggle source
# File lib/formwandler/form.rb, line 172
def initialize_fields
  @fields = self.class.field_definitions.transform_values do |field_definition|
    Field.new(form: self, field_definition: field_definition)
  end
end
initialize_models() click to toggle source
# File lib/formwandler/form.rb, line 111
def initialize_models
end
load_results() click to toggle source
# File lib/formwandler/form.rb, line 147
def load_results
  true
end
models_valid?() click to toggle source
# File lib/formwandler/form.rb, line 126
def models_valid?
  all_valid = true
  models.each do |name, model|
    next if model.valid?

    all_valid = false
    fields_for_model(name).each do |field|
      model.errors[field.source].each do |error_message|
        errors.add(field.name, error_message) unless errors.messages[field.source].include? error_message
      end
    end
  end
  all_valid
end
permitted_fields() click to toggle source
# File lib/formwandler/form.rb, line 159
def permitted_fields
  fields.reject(&:disabled?).map do |field|
    field.array? ? {field.name => []} : field.name
  end
end
permitted_params() click to toggle source
# File lib/formwandler/form.rb, line 155
def permitted_params
  controller.params.require(model_name.param_key).permit(*permitted_fields).delocalize(delocalizations)
end
save_models!() click to toggle source
# File lib/formwandler/form.rb, line 141
def save_models!
  models.sort_by do |(name, _model)|
    self.class.model_save_order&.index(name) || self.class.model_save_order&.size
  end.map(&:last).compact.each(&:save!)
end