Module: Glue::Orderable
- Includes:
- Aspects
- Defined in:
- lib/glue/orderable.rb
Overview
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.
Class Method Summary collapse
Instance Method Summary collapse
- #add_to ⇒ Object
- #add_to_bottom ⇒ Object
- #add_to_top ⇒ Object
- #bottom? ⇒ Boolean (also: #last?)
- #bottom_item ⇒ Object
- #bottom_position ⇒ Object
- #decrement_position ⇒ Object
- #decrement_position_of_lower_items ⇒ Object
- #higher_item ⇒ Object (also: #previous_item)
- #increment_position ⇒ Object
- #increment_position_of_all_items ⇒ Object
- #increment_position_of_higher_items ⇒ Object
- #lower_item ⇒ Object (also: #next_item)
-
#move_higher ⇒ Object
Move higher.
-
#move_lower ⇒ Object
Move lower.
-
#move_to(dest_position) ⇒ Object
Move to a specific position.
-
#move_to_bottom ⇒ Object
Move to the bottom.
-
#move_to_top ⇒ Object
Move to the top.
- #set_bottom_position ⇒ Object
- #set_top_position ⇒ Object
- #top? ⇒ Boolean (also: #first?)
- #top_item ⇒ Object (also: #first_item)
Class Method Details
.included_with_parameters(base, opt) ⇒ Object
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 |
# File 'lib/glue/orderable.rb', line 16 def self.included_with_parameters(base, opt) # The attribute to use to keep the position. opt_position = opt.fetch(:position, 'position') # The type of the position attribute. opt_type = opt.fetch(:type, Fixnum) # A user defined condition. opt_condition = opt[:condition] # A condition based on a key field (?) opt_scope = opt[:scope] # clean scope field. if opt_scope if opt_scope.to_s !~ /_oid$/ opt_scope = "#{opt_scope}_oid".to_sym else opt_scope = opt_scope.to_sym end end base.module_eval %{ attr_accessor :#{opt_position}, #{opt_type} def orderable_attribute #{opt_position.inspect} end def orderable_position @#{opt_position} end def orderable_position= (pos) @#{opt_position} = pos end def orderable_type #{opt_type} end def orderable_scope #{opt_scope.inspect} end def orderable_condition scope = orderable_scope if scope scope_value = send(scope) scope = scope_value ? "\#{scope} = \#{scope_value}" : "\#{scope} IS NULL" end return [ #{opt_condition.inspect}, scope ].compact end } end |
Instance Method Details
#add_to ⇒ Object
154 155 156 |
# File 'lib/glue/orderable.rb', line 154 def add_to # TODO end |
#add_to_bottom ⇒ Object
150 151 152 |
# File 'lib/glue/orderable.rb', line 150 def add_to_bottom self.orderable_position = bottom_position + 1 end |
#add_to_top ⇒ Object
146 147 148 |
# File 'lib/glue/orderable.rb', line 146 def add_to_top increment_position_of_all_items end |
#bottom? ⇒ Boolean Also known as: last?
190 191 192 |
# File 'lib/glue/orderable.rb', line 190 def bottom? self.orderable_position == bottom_position end |
#bottom_item ⇒ Object
177 178 179 180 181 182 |
# File 'lib/glue/orderable.rb', line 177 def bottom_item pos = orderable_attribute con = orderable_condition con = con.empty? ? nil : con.join(' AND ') self.class.one(:condition => con, :order => "#{pos} DESC", :limit => 1) end |
#bottom_position ⇒ Object
205 206 207 208 |
# File 'lib/glue/orderable.rb', line 205 def bottom_position item = bottom_item item ? (item.orderable_position || 0) : 0 end |
#decrement_position ⇒ Object
200 201 202 203 |
# File 'lib/glue/orderable.rb', line 200 def decrement_position self.orderable_position -= 1 update_attribute(self.orderable_attribute) end |
#decrement_position_of_lower_items ⇒ Object
233 234 235 236 237 |
# File 'lib/glue/orderable.rb', line 233 def decrement_position_of_lower_items pos = orderable_attribute con = orderable_condition + [ "#{pos} > #{orderable_position}" ] self.class.update "#{pos}=(#{pos} - 1)", :condition => con.join(' AND ') end |
#higher_item ⇒ Object Also known as: previous_item
158 159 160 161 162 |
# File 'lib/glue/orderable.rb', line 158 def higher_item pos = orderable_attribute con = orderable_condition + [ "#{pos} = #{orderable_position - 1}" ] self.class.one( :condition => con.join(' AND ') ) end |
#increment_position ⇒ Object
195 196 197 198 |
# File 'lib/glue/orderable.rb', line 195 def increment_position self.orderable_position += 1 update_attribute(self.orderable_attribute) end |
#increment_position_of_all_items ⇒ Object
226 227 228 229 230 231 |
# File 'lib/glue/orderable.rb', line 226 def increment_position_of_all_items pos = orderable_attribute con = orderable_condition con = con.empty? ? nil : con.join(' AND ') self.class.update "#{pos}=(#{pos} + 1)", :condition => con end |
#increment_position_of_higher_items ⇒ Object
220 221 222 223 224 |
# File 'lib/glue/orderable.rb', line 220 def increment_position_of_higher_items pos = orderable_attribute con = orderable_condition + [ "#{pos} < #{orderable_position}" ] self.class.update "#{pos}=(#{pos} + 1)", :condition => con.join(' AND ') end |
#lower_item ⇒ Object Also known as: next_item
165 166 167 168 169 |
# File 'lib/glue/orderable.rb', line 165 def lower_item pos = orderable_attribute con = orderable_condition + [ "#{pos} = #{orderable_position + 1}" ] self.class.one( :condition => con.join(' AND ') ) end |
#move_higher ⇒ Object
Move higher.
84 85 86 87 88 89 90 91 |
# File 'lib/glue/orderable.rb', line 84 def move_higher if higher = higher_item self.class.transaction do higher.increment_position decrement_position end end end |
#move_lower ⇒ Object
Move lower.
95 96 97 98 99 100 101 102 |
# File 'lib/glue/orderable.rb', line 95 def move_lower if lower = lower_item self.class.transaction do lower.decrement_position increment_position end end end |
#move_to(dest_position) ⇒ Object
Move to a specific position.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/glue/orderable.rb', line 124 def move_to(dest_position) return if self.orderable_position == dest_position pos = orderable_attribute con = orderable_condition self.class.transaction do if orderable_position < dest_position adj = "#{pos} = #{pos} - 1" con = con + [ "#{pos} > #{orderable_position}", "#{pos} <= #{dest_position}" ] else adj = "#{pos} = #{pos} + 1" con = con + [ "#{pos} < #{orderable_position}", "#{pos} >= #{dest_position}" ] end self.class.update( adj, :condition => con.join(' AND ') ) self.orderable_position = dest_position update_attribute(orderable_attribute) end self end |
#move_to_bottom ⇒ Object
Move to the bottom.
115 116 117 118 119 120 |
# File 'lib/glue/orderable.rb', line 115 def move_to_bottom self.class.transaction do decrement_position_of_lower_items set_bottom_position end end |
#move_to_top ⇒ Object
Move to the top.
106 107 108 109 110 111 |
# File 'lib/glue/orderable.rb', line 106 def move_to_top self.class.transaction do increment_position_of_higher_items set_top_position end end |
#set_bottom_position ⇒ Object
215 216 217 218 |
# File 'lib/glue/orderable.rb', line 215 def set_bottom_position self.orderable_position = bottom_position + 1 update_attribute(orderable_attribute) end |
#set_top_position ⇒ Object
210 211 212 213 |
# File 'lib/glue/orderable.rb', line 210 def set_top_position self.orderable_position = 1 update_attribute(orderable_attribute) end |
#top? ⇒ Boolean Also known as: first?
185 186 187 |
# File 'lib/glue/orderable.rb', line 185 def top? self.orderable_position == 1 end |
#top_item ⇒ Object Also known as: first_item
172 173 174 |
# File 'lib/glue/orderable.rb', line 172 def top_item # TODO end |