Class: Operations::Form

Inherits:
Object
  • Object
show all
Extended by:
Dry::Initializer
Defined in:
lib/operations/form.rb

Overview

This class implements Rails form object compatibility layer It is possible to configure form object attributes automatically basing on Dry Schema user Builder

Examples:


class AuthorForm < Operations::Form
  attribute :name
end

class PostForm < Operations::Form
  attribute :title
  attribute :tags, collection: true
  attribute :author, form: AuthorForm
end

PostForm.new({ tags: ["foobar"], author: { name: "Batman" } })
# => #<PostForm attributes={:title=>nil, :tags=>["foobar"], :author=>#<AuthorForm attributes={:name=>"Batman"}>}>

See Also:

Defined Under Namespace

Classes: Attribute, Builder

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name) ⇒ Object



84
85
86
# File 'lib/operations/form.rb', line 84

def method_missing(name, *)
  read_attribute(name)
end

Class Method Details

.attribute(name, **options) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/operations/form.rb', line 40

def self.attribute(name, **options)
  attribute = Operations::Form::Attribute.new(name, **options)

  self.attributes = attributes.merge(
    attribute.name => attribute
  )
end

.human_attribute_name(name, options = {}) ⇒ Object



48
49
50
51
52
53
54
# File 'lib/operations/form.rb', line 48

def self.human_attribute_name(name, options = {})
  if attributes[name.to_sym]
    attributes[name.to_sym].model_human_name(options)
  else
    name.to_s.humanize
  end
end

.validators_on(name) ⇒ Object



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

def self.validators_on(name)
  attributes[name.to_sym]&.model_validators || []
end

Instance Method Details

#assigned_attributesObject



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

def assigned_attributes
  (self.class.attributes.keys & data.keys).to_h do |name|
    [name, read_attribute(name)]
  end
end

#attributesObject



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

def attributes
  self.class.attributes.keys.to_h do |name|
    [name, read_attribute(name)]
  end
end

#errorsObject



108
109
110
111
112
113
114
115
116
117
# File 'lib/operations/form.rb', line 108

def errors
  @errors ||= ActiveModel::Errors.new(self).tap do |errors|
    self.class.attributes.each do |name, attribute|
      add_messages(errors, name, messages[name])
      add_messages_to_collection(errors, name, messages[name]) if attribute.collection
    end

    add_messages(errors, :base, messages[nil])
  end
end

#has_attribute?(name) ⇒ Boolean

rubocop:disable Naming/PredicateName

Returns:

  • (Boolean)


68
69
70
# File 'lib/operations/form.rb', line 68

def has_attribute?(name) # rubocop:disable Naming/PredicateName
  self.class.attributes.key?(name.to_sym)
end

#localized_attr_name_for(name, locale) ⇒ Object



64
65
66
# File 'lib/operations/form.rb', line 64

def localized_attr_name_for(name, locale)
  self.class.attributes[name.to_sym].model_localized_attr_name(locale)
end

#model_nameObject



92
93
94
# File 'lib/operations/form.rb', line 92

def model_name
  ActiveModel::Name.new(self.class)
end

#persisted?Boolean

This should return false if we want to use POST. Now it is going to generate PATCH form.

Returns:

  • (Boolean)


98
99
100
# File 'lib/operations/form.rb', line 98

def persisted?
  true
end

#read_attribute(name) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/operations/form.rb', line 123

def read_attribute(name)
  cached_attribute(name) do |value, attribute|
    if attribute.collection && attribute.form
      wrap_collection([name], value, attribute.form)
    elsif attribute.form
      wrap_object([name], value, attribute.form)
    elsif attribute.collection
      value.nil? ? [] : value
    else
      value
    end
  end
end

#respond_to_missing?(name) ⇒ Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/operations/form.rb', line 88

def respond_to_missing?(name, *)
  self.class.attributes.key?(name)
end

#to_keyObject

Probably can be always nil, it is used in automated URL derival. We can make it work later but it will require additional concepts.



104
105
106
# File 'lib/operations/form.rb', line 104

def to_key
  nil
end

#type_for_attribute(name) ⇒ Object



60
61
62
# File 'lib/operations/form.rb', line 60

def type_for_attribute(name)
  self.class.attributes[name.to_sym].model_type
end

#valid?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/operations/form.rb', line 119

def valid?
  errors.empty?
end