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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# File 'lib/codify/model_additions.rb', line 20
def attr_encoder attribute_name, options = {}
options = { :encoder => :none, :prefix => "encoded_", :suffix => "", :verb => "encode", :reverse_verb => "decode" }.merge(options.symbolize_keys)
encoder_type = options.delete(:encoder_type)
encoders = Array(options.delete(:encoder))
prefix = options.delete(:prefix)
suffix = options.delete(:suffix)
verb = options.delete(:verb)
reverse_verb = options.delete(:reverse_verb)
encoders.map! { |encoder| Encoders.find(encoder, encoder_type, options) }
encoders.each { |encoder| encoder.record = self if encoder.depends_on_record? }
attribute_name = attribute_name.to_sym
encoded_attribute_name = options.has_key?(:attribute) ? options.delete(:attribute) : "#{prefix}#{attribute_name}#{suffix}".to_sym
unencoded_ivar = "@_un#{encoded_attribute_name}".to_sym
old_unencoded_ivar = "@_old_un#{encoded_attribute_name}".to_sym
has_unencoded = attribute_names.include? attribute_name.to_s depends_on_record = encoders.any? { |encoder| encoder.depends_on_record? } reversible = encoders.all? { |encoder| encoder.decodes? }
define_method attribute_name do value = instance_variable_get unencoded_ivar
if value.nil? encoded_value = read_attribute(encoded_attribute_name)
if reversible && !encoded_value.blank?
value = Encoders.decode(encoders, encoded_value)
elsif has_unencoded
value = read_attribute(attribute_name)
end
instance_variable_set unencoded_ivar, value end
value
end
define_method "#{attribute_name}=".to_sym do |value|
encoded_value = Encoders.encode(encoders, value)
if !send("#{encoded_attribute_name}_changed?") instance_variable_set(old_unencoded_ivar, instance_variable_get(unencoded_ivar))
end
write_attribute(encoded_attribute_name, encoded_value)
instance_variable_set unencoded_ivar, value end
define_method "#{attribute_name}_changed?".to_sym do
send("#{encoded_attribute_name}_changed?")
end
define_method "#{attribute_name}_was".to_sym do instance_variable_get(old_unencoded_ivar) || begin
encoded_value = send("#{encoded_attribute_name}_was")
next (has_unencoded ? read_attribute(attribute_name) : nil) if encoded_value.blank?
value = Encoders.decode(encoders, encoded_value)
instance_variable_set(old_unencoded_ivar, value) end
end if reversible
define_method "#{attribute_name}_change".to_sym do
send("#{encoded_attribute_name}_changed?") ? [send("#{attribute_name}_was"), send(attribute_name)] : nil
end if reversible
define_method "#{attribute_name}?".to_sym do
if reversible
value = send attribute_name
else
value = send encoded_attribute_name
end
value && !value.blank?
end
after_initialize do |record| encoded_value = read_attribute(encoded_attribute_name)
instance_variable_set unencoded_ivar, Encoders.decode(encoders, encoded_value) unless encoded_value.blank?
end if reversible && depends_on_record
before_save do |record|
write_attribute(attribute_name, "") if has_unencoded && record.send("#{encoded_attribute_name}_changed?")
if depends_on_record && self.changed?
value = send(attribute_name)
write_attribute(encoded_attribute_name, Encoders.encode(encoders, value))
end
true
end
define_method "#{encoded_attribute_name}=".to_sym do |value| raise NoMethodError, "undefined method '#{encoded_attribute_name}=' for #{self}"
end
(class << self; self; end).instance_eval do
define_method [verb,attribute_name].join('_').to_sym do |data|
Encoders.encode(encoders,data)
end
define_method [reverse_verb,attribute_name].join('_').to_sym do |data|
Encoders.decode(encoders,data)
end
end if !depends_on_record
end
|