module Gourami::Attributes::ClassMethods

Public Instance Methods

attribute(name, options = {}, &default_block) click to toggle source

Define an attribute for the form.

@param name

The Symbol attribute name.

@option options

The type of this attribute. Can be any of :string, :integer,
:float, :array, :hash or :boolean.

@block default_block

If provided, the block will be applied to options as the :default
# File lib/gourami/attributes.rb, line 24
def attribute(name, options = {}, &default_block)
  base = self
  options = options.dup
  options[:default] = default_block if block_given?

  options_with_defaults = merge_default_attribute_options(options)

  mixin = Module.new do |mixin|
    unless options_with_defaults[:skip_reader]
      if !base.attributes.key?(name) && base.instance_methods.include?(name) && !options_with_defaults[:override_reader]
        raise AttributeNameConflictError, "#{name} is already a method. To use the existing method, use `:skip_reader => true` option. To override the existing method, use `:override_reader => true` option."
      end

      mixin.send(:define_method, :"#{name}") do
        value = instance_variable_get(:"@#{name}")
        default = options_with_defaults[:default]

        if value.nil? && default
          default.respond_to?(:call) ? instance_exec(&default) : default
        else
          value
        end
      end
    end

    # Define external setter.
    mixin.send(:define_method, :"#{name}=") do |value|
      provided_attributes_names[name.to_s] = options
      send(:"_#{name}=", value)
    end

    # Define internal setter.
    mixin.send(:define_method, :"_#{name}=") do |value|
      instance_variable_set(:"@#{name}", setter_filter(name, value, self.class.merge_default_attribute_options(options)))
    end
    mixin.send(:private, :"_#{name}=")

    case options[:type]
    when :boolean
      mixin.send(:define_method, :"#{name}?") do
        !!send(name)
      end
    end
  end

  include(mixin)

  attributes[name] = options
end
attributes() click to toggle source

Retrieve the list of attributes of the form.

@return [Hash]

The class attributes hash.
# File lib/gourami/attributes.rb, line 93
def attributes
  @attributes ||= {}
end
default_attribute_options() click to toggle source
# File lib/gourami/attributes.rb, line 103
def default_attribute_options
  @default_attribute_options ||= {}
end
inherited(klass) click to toggle source

Copy parent attributes to inheriting class.

@param klass [Class]

Calls superclass method
# File lib/gourami/attributes.rb, line 9
def inherited(klass)
  super(klass)
  klass.instance_variable_set(:@attributes, attributes.dup)
  klass.instance_variable_set(:@default_attribute_options, default_attribute_options.dup)
end
merge_default_attribute_options(options) click to toggle source
# File lib/gourami/attributes.rb, line 107
def merge_default_attribute_options(options)
  if options[:type]
    default_attribute_options.fetch(options[:type], {}).merge(options)
  else
    options
  end
end
record(name, options = {}) click to toggle source

Define the main record of this form (optional).

Record may be called with form_instance.record

@param name

The Symbol attribute name.

@option options [Class]

The Class of the type of this attribute. Can be any of String, Integer,
Float, Array, Hash or :boolean.
# File lib/gourami/attributes.rb, line 82
def record(name, options = {})
  define_method(:record) do
    send(name)
  end
  attribute(name, options.merge(:skip => true, :record => true))
end
set_default_attribute_options(attr_type, options) click to toggle source

Useful if you want, for example, all type: :string attributes to use strip: true to remove whitespace padding.

# File lib/gourami/attributes.rb, line 99
def set_default_attribute_options(attr_type, options)
  default_attribute_options[attr_type] = options
end