class ViewModel::Record

def attribute(attr, as: nil, read_only: false, write_once: false, using: nil, format: nil, array: false)

Specifies an attribute from the model to be serialized in this view
def attribute(attr, as: nil, read_only: false, write_once: false, using: nil, format: nil, array: false)
  model_attribute_name = attr.to_s
  vm_attribute_name    = (as || attr).to_s
  if using && format
    raise ArgumentError.new("Only one of ':using' and ':format' may be specified")
  end
  if using && !(using.is_a?(Class) && using < ViewModel)
    raise ArgumentError.new("Invalid 'using:' viewmodel: not a viewmodel class")
  end
  if using && using.root?
    raise ArgumentError.new("Invalid 'using:' viewmodel: is a root")
  end
  if format && !format.respond_to?(:dump) && !format.respond_to?(:load)
    raise ArgumentError.new("Invalid 'format:' serializer: must respond to :dump and :load")
  end
  attr_data = AttributeData.new(name: vm_attribute_name,
                                model_attr_name: model_attribute_name,
                                attribute_viewmodel: using,
                                attribute_serializer: format,
                                array: array,
                                read_only: read_only,
                                write_once: write_once)
  _members[vm_attribute_name] = attr_data
  @generated_accessor_module.module_eval do
    define_method vm_attribute_name do
      _get_attribute(attr_data)
    end
    define_method "serialize_#{vm_attribute_name}" do |json, serialize_context: self.class.new_serialize_context|
      _serialize_attribute(attr_data, json, serialize_context: serialize_context)
    end
    define_method "deserialize_#{vm_attribute_name}" do |value, references: {}, deserialize_context: self.class.new_deserialize_context|
      _deserialize_attribute(attr_data, value, references: references, deserialize_context: deserialize_context)
    end
  end
end