Module: Gourami::Attributes::ClassMethods

Defined in:
lib/gourami/attributes.rb

Instance Method Summary collapse

Instance Method Details

#attribute(name, options = {}, &default_block) ⇒ Object

Define an attribute for the form.

Parameters:

  • name

    The Symbol attribute name.

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • The (Object)

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



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 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

#attributesHash

Retrieve the list of attributes of the form.

Returns:

  • (Hash)

    The class attributes hash.



93
94
95
# File 'lib/gourami/attributes.rb', line 93

def attributes
  @attributes ||= {}
end

#default_attribute_optionsObject



103
104
105
# File 'lib/gourami/attributes.rb', line 103

def default_attribute_options
  @default_attribute_options ||= {}
end

#inherited(klass) ⇒ Object

Copy parent attributes to inheriting class.

Parameters:

  • klass (Class)


9
10
11
12
13
# 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) ⇒ Object



107
108
109
110
111
112
113
# 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 = {}, &block) ⇒ Object

Define the main record of this form (optional).

Record may be called with form_instance.record

Parameters:

  • name

    The Symbol attribute name.

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • The (Class)

    Class of the type of this attribute. Can be any of String, Integer, Float, Array, Hash or :boolean.



82
83
84
85
86
87
# File 'lib/gourami/attributes.rb', line 82

def record(name, options = {}, &block)
  define_method(:record) do
    send(name)
  end
  attribute(name, options.merge(:skip => true, :record => true), &block)
end

#set_default_attribute_options(attr_type, options) ⇒ Object

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



99
100
101
# File 'lib/gourami/attributes.rb', line 99

def set_default_attribute_options(attr_type, options)
  default_attribute_options[attr_type] = options
end