Module: TypeCast::ClassMethods

Defined in:
lib/type_cast.rb

Instance Method Summary collapse

Instance Method Details

#type_cast(*args) ⇒ Object Also known as: typecast



9
10
11
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
67
68
69
70
# File 'lib/type_cast.rb', line 9

def type_cast(*args)
  caster = args.pop
  if args.empty?
    raise ArgumentError, 'Instance methods for type casting supposed to be provided (e.g. type_cast :created_at, :updated_at, Time).'
  end
  if caster.respond_to?(:parse)
    args.each do |attribute|
      class_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{attribute}
          @#{attribute}_after_type_cast ||= begin
            uncasted = if defined?(super)
              super
            else
              method_missing(:#{attribute})
            end
            self.#{attribute}_before_type_cast = uncasted
            if uncasted.kind_of?(String)
              #{caster}.parse(uncasted)
            else
              uncasted
            end
          rescue
            uncasted
          end
        end
        attr_writer :#{attribute}_before_type_cast
        def #{attribute}_before_type_cast
          @#{attribute}_before_type_cast || (#{attribute}; #{attribute}_before_type_cast)
        end
      RUBY
    end
  elsif caster.respond_to?(:to_sym)
    conversion_method = caster.to_sym
    args.each do |attribute|
      class_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{attribute}
          @#{attribute}_after_type_cast ||= begin
            uncasted = if defined?(super)
              super
            else
              method_missing(:#{attribute})
            end
            self.#{attribute}_before_type_cast = uncasted
            if uncasted.respond_to?(:#{conversion_method})
              uncasted.__send__(:#{conversion_method})
            else
              uncasted
            end
          rescue
            uncasted
          end
        end
        attr_writer :#{attribute}_before_type_cast
        def #{attribute}_before_type_cast
          @#{attribute}_before_type_cast || (#{attribute}; #{attribute}_before_type_cast)
        end
      RUBY
    end
  else
    raise ArgumentError, 'Type casting needs an object with parse method or method name which should be called on casted attributes. Supply it as last argument (e.g. type_cast :created_at, Time).'
  end
end