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
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
|
# File 'lib/simple_enums.rb', line 11
def has_enum(name, options)
column_attr = "enum_#{name}_column"
enums_attr = "#{name}_enums"
default_attr = "default_#{name}_enum"
cattr_accessor column_attr, enums_attr, default_attr
self.enum_columns ||= []
self.enum_columns << name
self.send("#{column_attr}=", options[:column] || "#{name}_id")
self.send("#{enums_attr}=", options[:enums])
self.send("#{default_attr}=", options[:default] || options[:enums].first.first)
self.module_eval do
scope "#{name}_in", lambda{|s| where(self.send(column_attr).to_sym => self.send("#{name}_value", s)) }
self.class.send(:define_method, "#{name}_is") do |s|
self.send "#{name}_in", s
end
self.class.send(:define_method, "options_for_#{name}") do |*params|
if params.blank?
self.send(enums_attr).map{|s|[s.last, s.second]}
elsif params.first.is_a?(Symbol)
self.send(enums_attr).select{|e|params.include?(e.first)}.map{|s|[s.last, s.second]}
elsif params.first.is_a?(Array)
params.map{|p|[p.second, self.send(enums_attr).detect{|e|e.first == p.first}.try(:second)]}
end
end
self.class.send(:define_method, "#{name}_value") do |param|
if param.is_a?(Array)
param.map{|p|self.send("#{name}_value",p)}
elsif param.is_a?(Symbol)
self.send(enums_attr).assoc(param).try(:second)
elsif param.is_a?(String)
self.send(enums_attr).detect{|s| s.third == param }.try(:second)
else
param
end
end
self.class.send(:define_method, "#{name}_name") do |param|
self.send(enums_attr)
if param.is_a?(Symbol)
self.send(enums_attr).detect{|s| s.first == param }.try(:last)
elsif param.is_a?(String)
param
else
self.send(enums_attr).detect{|s| s.second == param }.try(:last)
end
end
self.send(:define_method, "#{name}_name") do
self.class.send(enums_attr).detect {|s| s.second == self.send(self.send(column_attr))}.try(:last)
end
self.send(:define_method, "#{name}_key") do
self.class.send(enums_attr).detect {|s| s.second == self.send(self.send(column_attr))}.try(:first)
end
self.send(:define_method, "set_#{name}_value") do |param|
value_id =
if param.is_a?(Symbol)
self.class.send("#{name}_value", param)
elsif param.is_a?(String)
self.send(enums_attr).detect {|s| s.last == param }.try(:second)
else
param
end
self.send("#{self.send(column_attr)}=", value_id)
value_id
end
self.send(:define_method, "update_#{name}_value") do |param|
self.send("set_#{name}_value", param)
self.save(:validate => false)
end
self.send(:define_method, "#{name}_is?") do |key|
if key.is_a?(Array)
key.detect{|p|self.send("#{name}_is?", p)}
else
self.class.send("#{name}_value", key) == self.send(self.send(column_attr))
end
end
self.send(:define_method, "set_#{name}_default_value") do
self.send("#{self.send(column_attr)}=", self.send("#{name}_default_value"))
end
self.send(:define_method, "#{name}_default_value") do
self.class.send("#{name}_value", self.send(default_attr))
end
alias_attribute name, self.send(column_attr) unless name.to_s == self.send(column_attr).to_s
end
end
|