Module: SerializedVirtualAttributes::ClassMethods

Defined in:
lib/serialized_virtual_attributes.rb

Instance Method Summary collapse

Instance Method Details

#serialized_virtual_attribute(*args) ⇒ Object

Raises:

  • (ArgumentError)


12
13
14
15
16
17
18
19
20
21
22
23
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
# File 'lib/serialized_virtual_attributes.rb', line 12

def serialized_virtual_attribute(*args)
  options = args.extract_options!
  to = options[:to]
  return unless self.column_names.include?(to.to_s)
  
  raise ArgumentError.new("option 'to' not provided or it is not serialized to hash") if to.blank? or self.serialized_attributes[to.to_s].try(:object_class) != Hash

  typecast = options[:typecast]

  self.serialized_virtual_attributes ||= {}
  self.serialized_virtual_attributes[to] ||= Set.new

  prefix = options[:prefix]

  args.each do |a|
    accessor_name = prefix.blank? ? a : :"#{prefix}_#{a}"
    self.serialized_virtual_attributes[to] += [accessor_name]
    class_eval "
      def #{accessor_name}
        self.#{to} = {} if self.#{to}.blank?

        self.#{to}[:#{a}]
      end
    "

    if typecast.blank?
      class_eval "
        def #{accessor_name}=(value)
          self.#{to} = {} if self.#{to}.blank?

          #{to}_will_change! unless value == self.#{to}[:#{a}]

          self.#{to}[:#{a}] = value
        end
      "
    else
      class_eval "
        def #{accessor_name}=(value)
          self.#{to} = {} if self.#{to}.blank?

          value = #{typecast.name}(value) rescue nil
          #{to}_will_change! unless value == self.#{to}[:#{a}]

          self.#{to}[:#{a}] = value
        end
      "
    end

    unless ActiveRecord::VERSION::MAJOR >= 4 or options[:accessible] == false
      class_eval "
        attr_accessible :#{accessor_name}
      "
    end
  end
end