Attach list/ordering methods to the enchanted class.

Comments

If you use the scope option, you have to set he parent (scope) of the object before inserting to have correct ordering.

Methods
Public Class methods
included_with_parameters(base, opt)
    # File lib/og/model/orderable.rb, line 14
14:   def self.included_with_parameters(base, opt)
15: 
16:     # The attribute to use to keep the position.
17:     
18:     opt_position = opt.fetch(:position, "position")
19: 
20:     # The type of the position attribute.
21:     
22:     opt_type = opt.fetch(:type, Fixnum)
23: 
24:     # A user defined condition.
25:     
26:     opt_condition = opt[:condition]
27: 
28:     # A condition based on a key field (?)
29:     
30:     opt_scope = opt[:scope]
31: 
32:     # clean scope field.
33:     
34:     if opt_scope
35:       if opt_scope.to_s !~ /_oid$/
36:         opt_scope = "#{opt_scope}_oid".to_sym
37:       else
38:         opt_scope = opt_scope.to_sym
39:       end
40:     end
41: 
42:     base.module_eval %{
43:       attr_accessor :#{opt_position}, #{opt_type}
44: 
45:       def orderable_attribute
46:         #{opt_position.inspect}
47:       end
48:           
49:       def orderable_position
50:         @#{opt_position}
51:       end
52: 
53:       def orderable_position= (pos)
54:         @#{opt_position} = pos
55:       end
56: 
57:       def orderable_type
58:         #{opt_type}
59:       end
60:    
61:       def orderable_scope
62:         #{opt_scope.inspect}
63:       end
64: 
65:       def orderable_condition
66:         scope = orderable_scope
67:         if scope
68:           scope_value = send(scope)
69:           scope = scope_value ? "\#{scope} = \#{scope_value}" : "\#{scope} IS NULL"
70:         end
71:         return [ #{opt_condition.inspect}, scope ].compact
72:       end
73:     }
74: 
75:   end
Public Instance methods
add_to()
     # File lib/og/model/orderable.rb, line 157
157:   def add_to
158:     # TODO
159:   end
add_to_bottom()
     # File lib/og/model/orderable.rb, line 153
153:   def add_to_bottom
154:     self.orderable_position = bottom_position + 1
155:   end
add_to_top()
     # File lib/og/model/orderable.rb, line 149
149:   def add_to_top
150:     increment_position_of_all_items
151:   end
bottom?()
This method is also aliased as last?
     # File lib/og/model/orderable.rb, line 193
193:   def bottom?
194:     self.orderable_position == bottom_position
195:   end
bottom_item()
     # File lib/og/model/orderable.rb, line 180
180:   def bottom_item
181:     pos = orderable_attribute
182:     con = orderable_condition
183:     con = con.empty? ? nil : con.join(' AND ')
184:     self.class.one(:condition => con, :order => "#{pos} DESC", :limit => 1)
185:   end
bottom_position()
     # File lib/og/model/orderable.rb, line 208
208:   def bottom_position
209:     item = bottom_item
210:     item ? (item.orderable_position || 0) : 0
211:   end
decrement_position()
     # File lib/og/model/orderable.rb, line 203
203:   def decrement_position
204:     self.orderable_position -= 1
205:     update_attribute(self.orderable_attribute)
206:   end
decrement_position_of_lower_items()
     # File lib/og/model/orderable.rb, line 236
236:   def decrement_position_of_lower_items
237:     pos = orderable_attribute
238:     con = orderable_condition + [ "#{pos} > #{orderable_position}" ]
239:     self.class.update "#{pos}=(#{pos} - 1)",  :condition => con.join(' AND ')
240:   end
first?()

Alias for #top?

first_item()

Alias for #top_item

higher_item()
This method is also aliased as previous_item
     # File lib/og/model/orderable.rb, line 161
161:   def higher_item
162:     pos = orderable_attribute
163:     con = orderable_condition + [ "#{pos} = #{orderable_position - 1}" ]
164:     self.class.one( :condition => con.join(' AND ') )
165:   end
increment_position()
     # File lib/og/model/orderable.rb, line 198
198:   def increment_position
199:     self.orderable_position += 1
200:     update_attribute(self.orderable_attribute)
201:   end
increment_position_of_all_items()
     # File lib/og/model/orderable.rb, line 229
229:   def increment_position_of_all_items
230:     pos = orderable_attribute
231:     con = orderable_condition
232:     con = con.empty? ? nil : con.join(' AND ')
233:     self.class.update "#{pos}=(#{pos} + 1)", :condition => con 
234:   end
increment_position_of_higher_items()
     # File lib/og/model/orderable.rb, line 223
223:   def increment_position_of_higher_items
224:     pos = orderable_attribute
225:     con = orderable_condition + [ "#{pos} < #{orderable_position}" ]
226:     self.class.update "#{pos}=(#{pos} + 1)",  :condition => con.join(' AND ')
227:   end
last?()

Alias for #bottom?

lower_item()
This method is also aliased as next_item
     # File lib/og/model/orderable.rb, line 168
168:   def lower_item
169:     pos = orderable_attribute
170:     con = orderable_condition + [ "#{pos} = #{orderable_position + 1}" ]
171:     self.class.one( :condition => con.join(' AND ') )
172:   end
move_higher()

Move higher.

    # File lib/og/model/orderable.rb, line 87
87:   def move_higher
88:     if higher = higher_item
89:       self.class.transaction do
90:         higher.increment_position
91:         decrement_position
92:       end
93:     end
94:   end
move_lower()

Move lower.

     # File lib/og/model/orderable.rb, line 98
 98:   def move_lower
 99:     if lower = lower_item
100:       self.class.transaction do
101:         lower.decrement_position
102:         increment_position
103:       end
104:     end
105:   end
move_to(dest_position)

Move to a specific position.

     # File lib/og/model/orderable.rb, line 127
127:   def move_to(dest_position)
128:     return if self.orderable_position == dest_position
129: 
130:     pos = orderable_attribute
131:     con = orderable_condition
132: 
133:     self.class.transaction do
134:       if orderable_position < dest_position
135:         adj = "#{pos} = #{pos} - 1"
136:         con = con + [ "#{pos} > #{orderable_position}", "#{pos} <= #{dest_position}" ]
137:       else
138:         adj = "#{pos} = #{pos} + 1"
139:         con = con + [ "#{pos} < #{orderable_position}", "#{pos} >= #{dest_position}" ]
140:       end
141:       self.class.update( adj, :condition => con.join(' AND ') )
142:       self.orderable_position = dest_position
143:       update_attribute(orderable_attribute)
144:     end
145: 
146:     self
147:   end
move_to_bottom()

Move to the bottom.

     # File lib/og/model/orderable.rb, line 118
118:   def move_to_bottom
119:     self.class.transaction do
120:       decrement_position_of_lower_items
121:       set_bottom_position
122:     end
123:   end
move_to_top()

Move to the top.

     # File lib/og/model/orderable.rb, line 109
109:   def move_to_top
110:     self.class.transaction do
111:       increment_position_of_higher_items
112:       set_top_position
113:     end
114:   end
next_item()

Alias for #lower_item

previous_item()

Alias for #higher_item

set_bottom_position()
     # File lib/og/model/orderable.rb, line 218
218:   def set_bottom_position
219:     self.orderable_position = bottom_position + 1
220:     update_attribute(orderable_attribute)
221:   end
set_top_position()
     # File lib/og/model/orderable.rb, line 213
213:   def set_top_position
214:     self.orderable_position = 1
215:     update_attribute(orderable_attribute)
216:   end
top?()
This method is also aliased as first?
     # File lib/og/model/orderable.rb, line 188
188:   def top?
189:     self.orderable_position == 1
190:   end
top_item()
This method is also aliased as first_item
     # File lib/og/model/orderable.rb, line 175
175:   def top_item
176:     # TODO
177:   end