acts_as_having_settings.rb
2.17 KB
1
2
3
4
5
6
7
8
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
module ActsAsHavingSettings
module ClassMethods
def acts_as_having_settings(*args)
options = args.last.is_a?(Hash) ? args.pop : {}
settings_field = options[:field] || 'settings'
class_eval <<-CODE
serialize :#{settings_field}, Hash
def self.settings_field
#{settings_field.inspect}
end
def #{settings_field}
self[:#{settings_field}] ||= Hash.new
end
def setting_changed?(setting_field)
setting_field = setting_field.to_sym
changed_settings = self.changes['#{settings_field}']
return false if changed_settings.nil?
old_setting_value = changed_settings.first.nil? ? nil : changed_settings.first[setting_field]
new_setting_value = changed_settings.last[setting_field]
old_setting_value != new_setting_value
end
before_save :symbolize_settings_keys
private
def symbolize_settings_keys
self[:#{settings_field}] && self[:#{settings_field}].symbolize_keys!
end
CODE
settings_items(*args)
end
def settings_items(*names)
options = names.last.is_a?(Hash) ? names.pop : {}
default = (!options[:default].nil?) ? options[:default].inspect : "val"
data_type = options[:type] || :string
names.each do |setting|
class_eval <<-CODE
def #{setting}
val = send(self.class.settings_field)[:#{setting}]
val.nil? ? (#{default}.is_a?(String) ? gettext(#{default}) : #{default}) : val
end
def #{setting}=(value)
h = send(self.class.settings_field).clone
h[:#{setting}] = self.class.acts_as_having_settings_type_cast(value, #{data_type.inspect})
send(self.class.settings_field.to_s + '=', h)
end
CODE
end
end
def acts_as_having_settings_type_cast(value, type)
# FIXME creating a new instance at every call, will the garbage collector
# be able to cope with it?
ActiveRecord::ConnectionAdapters::Column.new(:dummy, nil, type.to_s).type_cast(value)
end
end
end
ActiveRecord::Base.send(:extend, ActsAsHavingSettings::ClassMethods)