Class: LogicPro::Form

Inherits:
Dry::Struct
  • Object
show all
Includes:
ActiveModel::Validations
Defined in:
lib/logic_pro/form.rb

Constant Summary collapse

ATTRIBUTES_PROPERTIES =
%i[abstract as].freeze
Types =
LogicPro::Types

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input = {}) ⇒ Form

Returns a new instance of Form.



137
138
139
140
141
# File 'lib/logic_pro/form.rb', line 137

def initialize(input = {})
  prepare_input(input)
  @input = input
  super(input)
end

Instance Attribute Details

#inputObject (readonly)

Returns the value of attribute input.



11
12
13
# File 'lib/logic_pro/form.rb', line 11

def input
  @input
end

Class Method Details

.attribute(name, type = nil, options = {}, &block) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/logic_pro/form.rb', line 27

def attribute(name, type = nil, options = {}, &block)
  @attributes_details ||= {}
  @attributes_details[name] = options.slice(*ATTRIBUTES_PROPERTIES).merge(type: type)

  return super(name, &block) if type.blank?

  super(name, type.meta(omittable: true))

  define_method("#{name}=") do |value|
    input[name.to_sym] = value
  end

  if nested_form?(type)
    define_method("#{name}_form") do
      nested_forms[name.to_sym]
    end
  end

  if nested_array_of_forms?(type)
    define_method("#{name}_forms") do
      nested_forms[name.to_sym]
    end
  end
end

.attribute_entities(name, type, options = {}) ⇒ Object



61
62
63
64
# File 'lib/logic_pro/form.rb', line 61

def attribute_entities(name, type, options = {})
  attribute(name, type, options.merge(as: :entities))
  attribute("#{name}_ids".to_sym, Types::Strict::Array.of(Types::Coercible::Integer), abstract: true)
end

.attribute_entity(name, type, options = {}) ⇒ Object



56
57
58
59
# File 'lib/logic_pro/form.rb', line 56

def attribute_entity(name, type, options = {})
  attribute(name, type, options.merge(as: :entity))
  attribute("#{name}_id".to_sym, Types::Coercible::String, abstract: true)
end

.attributes_detailsObject



52
53
54
# File 'lib/logic_pro/form.rb', line 52

def attributes_details
  @attributes_details || {}
end

.failure_parse!(error) ⇒ Object



78
79
80
81
82
83
# File 'lib/logic_pro/form.rb', line 78

def failure_parse!(error)
  entity = new
  entity.errors.add(:base, error.message)

  entity
end

.fieldsObject



72
73
74
75
76
# File 'lib/logic_pro/form.rb', line 72

def fields
  @fields ||= attributes_details.reject do |_key, details|
    nested_form?(details[:type]) || nested_array_of_forms?(details[:type])
  end
end

.from_entity(entity) ⇒ Object



21
22
23
24
25
# File 'lib/logic_pro/form.rb', line 21

def from_entity(entity)
  new(build_attribute_entity(entity))
rescue => error
  failure_parse!(error)
end

.from_params(params) ⇒ Object



14
15
16
17
18
19
# File 'lib/logic_pro/form.rb', line 14

def from_params(params)
  resource_params = params&.permit! || {}
  new(resource_params)
rescue => error
  failure_parse!(error)
end

.nested_formsObject



66
67
68
69
70
# File 'lib/logic_pro/form.rb', line 66

def nested_forms
  @nested_forms ||= attributes_details.select do |_key, details|
    nested_form?(details[:type]) || nested_array_of_forms?(details[:type])
  end
end

Instance Method Details

#base_errorsObject



155
156
157
158
159
160
# File 'lib/logic_pro/form.rb', line 155

def base_errors
  base = errors[:base]
  base += nested_forms.keys.map { |key| errors[key].present? ? errors[key][:base] : nil }

  base.flatten.compact
end

#failure?Boolean

Returns:

  • (Boolean)


166
167
168
# File 'lib/logic_pro/form.rb', line 166

def failure?
  !valid?
end

#fieldsObject



180
181
182
183
184
185
186
187
188
189
190
# File 'lib/logic_pro/form.rb', line 180

def fields
  @fields ||= self.class.fields.map do |name, field_details|
    additional_field_details = field_details.slice(*ATTRIBUTES_PROPERTIES).map do |key, value|
      value = respond_to?(value.to_s) ? send(value) : value

      [key, value]
    end.to_h

    [name, field_details.merge(additional_field_details)]
  end.to_h
end

#invalid?Boolean

Returns:

  • (Boolean)


162
163
164
# File 'lib/logic_pro/form.rb', line 162

def invalid?
  !valid?
end

#key?(key) ⇒ Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/logic_pro/form.rb', line 133

def key?(key)
  input.keys.include?(key)
end

#nested_formsObject



174
175
176
177
178
# File 'lib/logic_pro/form.rb', line 174

def nested_forms
  @nested_forms ||= self.class.nested_forms.map do |key, details|
    [key, build_nested_form_attribute(details[:type], key, input)]
  end.to_h
end

#paramsObject



143
144
145
# File 'lib/logic_pro/form.rb', line 143

def params
  to_h.slice(*input.keys.map(&:to_sym))
end

#success?Boolean

Returns:

  • (Boolean)


170
171
172
# File 'lib/logic_pro/form.rb', line 170

def success?
  valid?
end

#valid?Boolean

Returns:

  • (Boolean)


147
148
149
150
151
152
153
# File 'lib/logic_pro/form.rb', line 147

def valid?
  return false if errors.any?

  super()
  assign_nested_forms_errors(errors)
  errors.messages.blank?
end