Class: ROM::Model::Form

Inherits:
Object
  • Object
show all
Extended by:
ClassMacros, ClassInterface
Defined in:
lib/rom/rails/model/form.rb,
lib/rom/rails/model/form/error_proxy.rb,
lib/rom/rails/model/form/class_interface.rb

Overview

Abstract form class

Form objects in ROM are your top-level interface to persist data in the database. They combine many features that you know from ActiveRecord:

* params processing with sanitization and coercion
* attribute validations
* persisting data in the database

The major difference is that a ROM form object separates those responsibilities - a ROM form class has its own Attributes, Validator and ROM commands that are accessible within its instance.

Examples:

class UserForm < ROM::Model::Form
  commands users: :create

  input do
    set_model_name 'User'

    attribute :name, String
  end

  validations do
    validates :name, presence: true
  end
end

class CreateUserForm < UserForm
  attributes.timestamps :created_at

  def commit!
    users.try { users.create.call(attributes) }
  end
end

# then in your controller
CreateUserForm.build(params[:user]).save

Defined Under Namespace

Modules: ClassInterface Classes: ErrorProxy

Instance Attribute Summary collapse

Attributes included from ClassInterface

#injectible_commands, #self_commands, #validator

Instance Method Summary collapse

Methods included from ClassInterface

build, commands, inherited, inject_commands_for, input, key, validations

Constructor Details

#initialize(params = {}, options = {}) ⇒ Form

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Form.



94
95
96
97
98
99
100
# File 'lib/rom/rails/model/form.rb', line 94

def initialize(params = {}, options = {})
  @params = params
  @model  = self.class.model.new(params.merge(options.slice(*self.class.key)))
  @result = nil
  @errors = ErrorProxy.new
  options.each { |key, value| instance_variable_set("@#{key}", value) }
end

Instance Attribute Details

#errorsErrorProxy (readonly)

Return any errors with the form

Returns:



84
85
86
# File 'lib/rom/rails/model/form.rb', line 84

def errors
  @errors
end

#modelObject (readonly) Also known as: to_model

Return model instance representing an ActiveModel object that will be persisted or updated

Returns:

  • (Object)


70
71
72
# File 'lib/rom/rails/model/form.rb', line 70

def model
  @model
end

#paramsObject (readonly)

Return raw params received from the request

Returns:

  • (Object)


62
63
64
# File 'lib/rom/rails/model/form.rb', line 62

def params
  @params
end

#resultObject (readonly)

Return the result of commit!

Returns:

  • (Object)


77
78
79
# File 'lib/rom/rails/model/form.rb', line 77

def result
  @result
end

Instance Method Details

#attributesModel::Attributes

Sanitize and coerce input params

This can also set default values

Returns:

  • (Model::Attributes)


152
153
154
# File 'lib/rom/rails/model/form.rb', line 152

def attributes
  self.class.attributes[params]
end

#commit!Object

This method is abstract.

A specialized form object must implement this method

Raises:

  • (NotImplementedError)


107
108
109
# File 'lib/rom/rails/model/form.rb', line 107

def commit!
  raise NotImplementedError, "#{self.class}#commit! must be implemented"
end

#save(*args) ⇒ self

Save a form by calling commit! and memoizing result

Returns:

  • (self)


116
117
118
119
120
121
122
123
# File 'lib/rom/rails/model/form.rb', line 116

def save(*args)
  @errors.clear
  @result = commit!(*args)

  @errors.set @result.error if result.respond_to? :error

  self
end

#success?TrueClass, FalseClass

Return whether commit was successful

Returns:

  • (TrueClass, FalseClass)


130
131
132
# File 'lib/rom/rails/model/form.rb', line 130

def success?
  errors.success?
end

#validate!Object

Trigger validation and store errors (if any)



137
138
139
140
141
142
143
# File 'lib/rom/rails/model/form.rb', line 137

def validate!
  @errors.clear
  validator = self.class::Validator.new(attributes)
  validator.validate

  @errors.set validator.errors
end