Class: Flattener::Configurator

Inherits:
Object
  • Object
show all
Defined in:
lib/flattener/configurator.rb

Direct Known Subclasses

NestedConfigurator

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, name, options = {}, &block) ⇒ Configurator

Returns a new instance of Configurator.



16
17
18
19
20
21
22
23
24
25
# File 'lib/flattener/configurator.rb', line 16

def initialize(klass, name, options = {}, &block)
  @klass = klass
  @name = name
  @options = options
  @flattened_attrs = {}
  @prefix = @options[:prefix] || @name.to_s
  @accessor = @options[:accessor] || @name.to_s
  prepare!
  self.instance_eval(&block) if block_given?
end

Instance Attribute Details

#accessorObject

Returns the value of attribute accessor.



14
15
16
# File 'lib/flattener/configurator.rb', line 14

def accessor
  @accessor
end

#flattened_attrsObject

Returns the value of attribute flattened_attrs.



14
15
16
# File 'lib/flattener/configurator.rb', line 14

def flattened_attrs
  @flattened_attrs
end

#klassObject

Returns the value of attribute klass.



14
15
16
# File 'lib/flattener/configurator.rb', line 14

def klass
  @klass
end

#nameObject

Returns the value of attribute name.



14
15
16
# File 'lib/flattener/configurator.rb', line 14

def name
  @name
end

#optionsObject

Returns the value of attribute options.



14
15
16
# File 'lib/flattener/configurator.rb', line 14

def options
  @options
end

#prefixObject

Returns the value of attribute prefix.



14
15
16
# File 'lib/flattener/configurator.rb', line 14

def prefix
  @prefix
end

Class Method Details

.flat(klass, object, options = {}, &block) ⇒ Object



5
6
7
# File 'lib/flattener/configurator.rb', line 5

def self.flat klass, object, options = {}, &block
  new klass, object, options, &block
end

Instance Method Details

#accessor_method_nameObject

How it access the flattened object



83
84
85
# File 'lib/flattener/configurator.rb', line 83

def accessor_method_name
  @accessor
end

#add_build_method!Object



40
41
42
43
44
45
# File 'lib/flattener/configurator.rb', line 40

def add_build_method!
  unless @klass.instance_methods.include?(build_method_name.to_sym)
    raise "must specify a build option, or the method named #{build_method_name}" unless @options.has_key?(:build)
    @klass.send :define_method, build_method_name, &@options[:build] 
  end
end

#add_proxy_method!Object



47
48
49
50
51
52
53
54
55
56
# File 'lib/flattener/configurator.rb', line 47

def add_proxy_method!
  @klass.class_eval <<-CODE, __FILE__, __LINE__ 
    def #{proxy_method_name}
      if self.#{accessor_method_name}.nil?
        #{build_method_name} 
      end
      self.#{accessor_method_name}
    end
  CODE
end

#add_validator_method!Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/flattener/configurator.rb', line 58

def add_validator_method!
  if validations_are_supported?
    @klass.class_eval <<-CODE, __FILE__, __LINE__  
      def #{validate_method_name} 
        unless self.#{accessor_method_name}.blank?
          self.#{proxy_method_name}.valid?

          self.#{proxy_method_name}.errors.each do |name, messages|
            flattened_name = self.class.flatteners[:#{name}].flattened_attrs[name]
            messages = [messages].flatten
            unless flattened_name.nil?
              messages.each do |message|
                self.errors.add flattened_name, message
              end
            end
          end
        end
      end
    CODE
    
    @klass.validate validate_method_name
  end
end

#attribute(name) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/flattener/configurator.rb', line 113

def attribute(name)
  method_name = method_name_for(name)
  @klass.class_eval <<-CODE, __FILE__, __LINE__
    def #{method_name}
      #{proxy_method_name}.#{name}
    end

    def #{method_name}=(value)
      #{proxy_method_name}.#{name} = value
    end
  CODE
  if mass_assignment_is_supported?
    @klass.attr_accessible method_name.to_sym
  end
  flattened_attrs[name] = method_name
end

#attributes(*names) ⇒ Object



107
108
109
110
111
# File 'lib/flattener/configurator.rb', line 107

def attributes(*names)
  names.each do |name|
    attribute name
  end
end

#build_method_nameObject



91
92
93
# File 'lib/flattener/configurator.rb', line 91

def build_method_name
  "build_#{accessor_method_name}"
end

#flat(object, options = {}, &block) ⇒ Object

# nesting



10
11
12
# File 'lib/flattener/configurator.rb', line 10

def flat object, options = {}, &block
  NestedConfigurator.new self, object, options, &block
end

#mass_assignment_is_supported?Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/flattener/configurator.rb', line 130

def mass_assignment_is_supported?
  module_included?(ActiveModel::MassAssignmentSecurity)
end

#method_name_for(name) ⇒ Object



99
100
101
102
103
104
105
# File 'lib/flattener/configurator.rb', line 99

def method_name_for(name)
  if prefix.blank?
    name.to_sym
  else
    "#{prefix}_#{name}".to_sym
  end
end

#module_included?(m) ⇒ Boolean

Returns:

  • (Boolean)


138
139
140
# File 'lib/flattener/configurator.rb', line 138

def module_included?(m)
  defined?(m) && @klass.included_modules.include?(m)
end

#prepare!Object



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/flattener/configurator.rb', line 27

def prepare!
  add_build_method!
  add_proxy_method!
  add_validator_method!

  unless klass.respond_to?(:flatteners)
    klass.class_attribute :flatteners
    klass.flatteners = {}
  end

  klass.flatteners[name] = self
end

#proxy_method_nameObject



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

def proxy_method_name
  "proxy_#{accessor_method_name}"
end

#validate_method_nameObject



95
96
97
# File 'lib/flattener/configurator.rb', line 95

def validate_method_name
  "validate_#{accessor_method_name}"
end

#validations_are_supported?Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/flattener/configurator.rb', line 134

def validations_are_supported?
  module_included?(ActiveModel::Validations)
end