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
|
# File 'lib/me_first.rb', line 7
def attr_orderable(*attrs)
attrs.each do |att|
metaclass.instance_eval do
define_method "by_#{att}" do
self.order(att => :asc)
end
define_method "by_reverse_#{att}" do
self.order(att => :desc)
end
end
class_eval do
define_method "move_#{att}_to_end!" do
others = self.class.send("by_#{att}").where.not(id: self.id).to_a
save_to_db( others.concat([self]), att)
end
define_method "set_#{att}!" do |new_order|
new_order = 0 if new_order < 0
others = self.class.send("by_#{att}").where.not(id: self.id).to_a
if new_order > others.length + 1
self.send("move_#{att}_to_end!")
else
others.insert( new_order, self )
save_to_db( others, att )
end
end
define_method "move_#{att}_to_beginning!" do
send("set_#{att}!", 0)
end
define_method "move_#{att}_up!" do |num=1|
send("set_#{att}!", self.order + num)
end
define_method "move_#{att}_down!" do |num=1|
send("set_#{att}!", self.order - num)
end
define_method "save_to_db" do |items, att|
ActiveRecord::Base.transaction do
items.compact.each_with_index do |item, index|
item.send( "#{att}=", index )
item.save!
end
end
end
private :save_to_db
end
end
end
|