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
|
# File 'lib/freezer/active_record_extensions.rb', line 10
def has_one_frozen(association_name, options = {})
options.reverse_merge!({
class_name: association_name.to_s,
column_name: "frozen_#{association_name.to_s}",
slient: false
})
klass = options[:class_name]
klass = klass.to_s.camelize.constantize unless Class === klass
accessor_name = association_name.to_s.underscore
serializer = if self.columns_hash[options[:column_name].to_s].type == :hstore
require 'freezer/serialization/hstore'
::Freezer::Serialization::HStore
else
require 'freezer/serialization/serialize'
self.serialize options[:column_name].to_sym, Hash
::Freezer::Serialization::Serialize
end
define_method(accessor_name) do
@freezer_cache ||= {}
if @freezer_cache.key? accessor_name
return @freezer_cache[accessor_name]
end
if hstore = read_attribute(options[:column_name])
@freezer_cache[accessor_name] = serializer.deserialize(options[:class_name], hstore, options[:slient])
else
@freezer_cache[accessor_name] = nil
end
@freezer_cache[accessor_name]
end
define_method("#{accessor_name}=") do |record|
unless record.nil? || record.is_a?(klass)
message = "#{klass}(##{klass.object_id}) expected, got #{record.class}(##{record.class.object_id})"
raise ArgumentError, message
end
@freezer_cache ||= {}
if record
write_attribute(options[:column_name], serializer.serialize(record))
else
write_attribute(options[:column_name], nil)
end
@freezer_cache.delete(accessor_name)
self.__send__(accessor_name.to_sym)
end
end
|