Module: DynamicAttributeDeclaration::ClassMethods

Defined in:
lib/dynamic_attribute_declaration.rb

Instance Method Summary collapse

Instance Method Details

#add_dynamic_attrs(attrs) ⇒ Object



115
116
117
118
119
120
121
122
123
124
# File 'lib/dynamic_attribute_declaration.rb', line 115

def add_dynamic_attrs attrs
  attrs.each do |attr|
    key, value = *attr.flatten
    if self._dynamic_attrs.keys.include? key
      self._dynamic_attrs[key].push process_attr(value)
    else
      self._dynamic_attrs[key] = [process_attr(value)]
    end
  end
end

#attrs_for(state = nil, device = nil) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/dynamic_attribute_declaration.rb', line 69

def attrs_for state=nil, device=nil
  if state && state.to_sym != :all
    state = state.to_sym
    device = device ? device.to_sym : nil
    devices = [:all, device].compact.uniq

    _dynamic_attrs.select do |attr_name, definitions|
      on_attrs = attrs_on_for(attr_name)
      if on_attrs
        comparer = (devices & on_attrs.keys).map { |k| on_attrs[k] }.flatten.uniq
      end
      comparer.map(&:to_sym).include? state.to_sym
    end
  else
    _dynamic_attrs
  end
end

#attrs_names_for(state = nil, device = nil) ⇒ Object



87
88
89
# File 'lib/dynamic_attribute_declaration.rb', line 87

def attrs_names_for state=nil, device=nil
  attrs_for(state, device).map(&:first)
end

#attrs_on_for(attr_name) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/dynamic_attribute_declaration.rb', line 49

def attrs_on_for attr_name
  attr = _dynamic_attrs[attr_name]
  if attr && !attr.empty?
    rtn = {}
    attr.each do |a|
      if a.key? :on
        obj = a[:on]
        obj.each do |key, value|
          if rtn.key? key
            rtn[key].push(value).flatten!.uniq!
          else
            rtn[key] = value
          end
        end
      end
    end
    rtn
  end
end

#build_validations_from_dynamic_attrs(attrs) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/dynamic_attribute_declaration.rb', line 91

def build_validations_from_dynamic_attrs attrs
  # throw "No validation state if defined" unless _rdynamic_attr_state_if
  attrs.each do |attr|
    key, value = *attr.flatten
    if value.key?(:validates) && !value[:validates].empty?
      opts = value[:validates].deep_symbolize_keys

      # Check if validation should only be used in specific state
      if value.key?(:on) && _dynamic_attr_state_if && _dynamic_attr_state_if.class == Proc
        validates_on = value[:on]
        # If validates contains if statement, wrap that statement in state check
        if opts.key?(:if)
          original_if = opts.delete(:if)
          opts.merge! if: ->(model) { model.instance_exec(validates_on, &_dynamic_attr_state_if) && model.instance_eval(&original_if) }
        else
          opts.merge! if: ->(model) { model.instance_exec(validates_on, &_dynamic_attr_state_if) }
        end
      end

      validates key.to_sym, opts
    end
  end
end

#clear_dynamic_attrs!Object



34
35
36
37
# File 'lib/dynamic_attribute_declaration.rb', line 34

def clear_dynamic_attrs!
  self._dynamic_attrs = {}
  self._dynamic_attr_state_if = nil
end

#define_attr_state_if(proc) ⇒ Object



39
40
41
42
# File 'lib/dynamic_attribute_declaration.rb', line 39

def define_attr_state_if proc
  throw "define_attr_state_if should be a proc" unless proc.class == Proc
  self._dynamic_attr_state_if = proc
end

#define_attrs(args) ⇒ Object



44
45
46
47
# File 'lib/dynamic_attribute_declaration.rb', line 44

def define_attrs args
  add_dynamic_attrs args
  build_validations_from_dynamic_attrs args
end

#inherited(base) ⇒ Object

:nodoc:



27
28
29
30
31
32
# File 'lib/dynamic_attribute_declaration.rb', line 27

def inherited(base) #:nodoc:
  dup = _dynamic_attrs.dup
  base._dynamic_attrs = dup.each { |k, v| dup[k] = v.dup }
  base._dynamic_attr_state_if = nil
  super
end

#process_attr(attr) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/dynamic_attribute_declaration.rb', line 126

def process_attr attr
  rtn = {}
  attr.each do |key, value|
    if key == :on
      case value
      when Symbol
        new_value = { all: [value] }
      when Array
        new_value = { all: value }
      when Hash
        new_value = {}
        value.each { |k,v| new_value[k] = *v }
      else
        throw "Process attr #{value} cannot be of class #{value.class}"
      end
    else
      new_value = value
    end
    rtn[key] = new_value
  end
  rtn
end