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
- add_to
- add_to_bottom
- add_to_top
- bottom?
- bottom_item
- bottom_position
- decrement_position
- decrement_position_of_lower_items
- first?
- first_item
- higher_item
- included_with_parameters
- increment_position
- increment_position_of_all_items
- increment_position_of_higher_items
- last?
- lower_item
- move_higher
- move_lower
- move_to
- move_to_bottom
- move_to_top
- next_item
- previous_item
- set_bottom_position
- set_top_position
- top?
- top_item
Public Class methods
[ show source ]
# 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
[ show source ]
# File lib/og/model/orderable.rb, line 157
157: def add_to
158: # TODO
159: end
[ show source ]
# File lib/og/model/orderable.rb, line 153
153: def add_to_bottom
154: self.orderable_position = bottom_position + 1
155: end
[ show source ]
# File lib/og/model/orderable.rb, line 149
149: def add_to_top
150: increment_position_of_all_items
151: end
This method is also aliased as
last?
[ show source ]
# File lib/og/model/orderable.rb, line 193
193: def bottom?
194: self.orderable_position == bottom_position
195: end
[ show source ]
# 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
[ show source ]
# 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
[ show source ]
# 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
[ show source ]
# 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
Alias for #top?
Alias for #top_item
This method is also aliased as
previous_item
[ show source ]
# 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
[ show source ]
# 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
[ show source ]
# 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
[ show source ]
# 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
Alias for #bottom?
This method is also aliased as
next_item
[ show source ]
# 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.
[ show source ]
# 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.
[ show source ]
# 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 a specific position.
[ show source ]
# 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 the bottom.
[ show source ]
# 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 the top.
[ show source ]
# 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
Alias for #lower_item
Alias for #higher_item
[ show source ]
# 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
[ show source ]
# 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
This method is also aliased as
first?
[ show source ]
# File lib/og/model/orderable.rb, line 188
188: def top?
189: self.orderable_position == 1
190: end
This method is also aliased as
first_item
[ show source ]
# File lib/og/model/orderable.rb, line 175
175: def top_item
176: # TODO
177: end