module FormObject::Mapping

Direct including types

Defined in:

form_object/mapping.cr

Macro Summary

Macro Detail

macro attr(name, type, origin = nil, virtual = false) #

Specifies attribute being parsed from a given request.

Options:

  • name - form object attribute name
  • type - attribute type; to define nilable field use Type? notation
  • origin - related model attribute name (by default it is name)
  • virtual - marks attribute as virtual - it will be retrieved and validated but no synchronized with model (false by default)
class ContactForm < FormObject::Base(Contact)
  attr :name, String
  attr :sex, String, origin: :gender
  attr :count, Int32, virtual: true
  attr :_deleted, Bool?, virtual: true
end

Any defined field of form object is defined as nilable. For a non-nil field #attribute method performs #not_nil! check.

Defines next methods for field with name attribute:

  • #attribute! - getter with not_nil! check for non-nil field
  • #attribute - getter without not_nil! check
  • #append_attribute(String) - coerces given value and adds to attribute (if it is an array)
  • #attribute=(Type) - setter
  • #attribute=(String) - coerces given value and sets to attribute

[View source]
macro collection(name, klass, form_class = nil, origin = nil, save = true, populator = nil) #

Specifies relation collection being parsed from a given request.

Options:

  • name - nested form object name
  • klass - nested resource type
  • form_class - form object class for a resource; (by default is "#{klass.id}Form".id)
  • origin - related model relation name (by default is name)
  • save - whether related model should be persisted (by default is true)
  • populator - method name that will be used for object population.
class ContactForm < FormObject::Base(Contact)
  collection :addresses, Address, populator: :populate_address

  def populate_address_collection(collection, index, **opts)
    if collection[index]?
      collection[index]
    else
      form = AddressForm.new(Address.new({contact_id: resource.id}))
      addresses << form
      form
    end
  end
end

Populator method is called for an object with following named tuple: `{collection: Array(ModelForm), context: FormObject::Context, index: Int32}. Populator should return ModelForm object - this is required.

Defines next methods for field with name attribute:

  • #collection! - same as #collection
  • #collection - getter without not_nil! check
  • #collection=(Array(Model)) - wraps given model in Array(ModelForm)
  • #collection=(Array(ModelForm)) - setter
  • #add_collection(Model) - adds given model to collection wrapping it into form object

[View source]
macro json_path(value) #

Specifies path to the root of defined object.

value - array of exact json keys.

class AdditionalInfoForm < FormObject::Base(AdditionalInfo)
  json_path %w(additionalInfo data)

  # ...
end

[View source]
macro object(name, klass, form_class = nil, origin = nil, save = true, populator = nil) #

Specifies nested object form being parsed from a given request.

Options:

  • name - nested form object name
  • klass - nested resource type
  • form_class - form object class for a resource; (by default is "#{klass.id}Form".id)
  • origin - related model relation name (by default is name)
  • save - whether related model should be persisted (by default is true)
  • populator - method name that will be used for object population.
class ContactForm < FormObject::Base(Contact)
  object :address, Address, populator: :populate_address

  def populate_address(model, **opts)
    model || Address.new
  end
end

Any defined nested object of form object is defined as nilable.

Populator method is called for the object with following named tuple: `{model: ModelForm?, context: FormObject::Context}. Populator should return ModelForm object - this is required.

In the code snippet above described default populator that is generated if no populator is given.

Defines next methods for field with name attribute:

  • #object! - getter with not_nil! check
  • #object - getter without not_nil! check
  • #object=(Model) - wraps given model in ModelForm
  • #object=(ModelForm) - setter

[View source]
macro path(value) #

Specifies the root name for the form data or URL parameters.

value - string representation of root name; if it is not specified all fields will be retrieved from the root scope.

class AdditionalInfoForm < FormObject::Base(AdditionalInfo)
  path "additional_info[data]"

  # ...
end

[View source]