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
|
# File 'lib/enum_set.rb', line 11
def enum_set(enums)
enums.each do |column, names|
if !names.is_a?(Hash)
names = Hash[
names.each_with_index.map do |name, i|
[name, 1 << i]
end
]
end
names_with_bits = names.symbolize_keys
define_method :"#{column}_bitfield" do
self[column] || 0
end
names_with_bits.each do |name, bit|
define_method :"#{name}?" do
(bit & send("#{column}_bitfield")) != 0
end
scope :"#{name}", -> {
where("#{column} & ? <> 0", bit)
}
end
define_method :"#{column}=" do |values|
case values
when Array
values.each do |val|
raise EnumError.new("Unrecognized value for #{column}: #{val.inspect}") unless names.include?(val)
end
current_value = send("#{column}_bitfield")
new_value = values.reduce(current_value) do |acc, val|
acc | names_with_bits[val.to_sym]
end
when Fixnum
new_value = values
end
self[column] = new_value
send(column)
end
define_method column do
names_with_bits.keys.select { |name| send(:"#{name}?") }
end
end
end
|