Module: RailsExtensions::HabtmList::AssociationListMethods
- Defined in:
- lib/webpulser-habtm_list.rb
Instance Method Summary collapse
- #add_to_list_bottom(item) ⇒ Object
- #add_to_list_top(item) ⇒ Object
- #assume_bottom_position(item) ⇒ Object
- #assume_top_position(item) ⇒ Object
- #decrement_position(item) ⇒ Object
-
#decrement_positions_on_higher_items(position) ⇒ Object
This has the effect of moving all the higher items up one.
-
#decrement_positions_on_lower_items(item) ⇒ Object
This has the effect of moving all the lower items up one.
- #first?(item) ⇒ Boolean
- #foreign_key ⇒ Object
- #higher_item(item) ⇒ Object
- #in_list?(item) ⇒ Boolean
- #increment_position(item) ⇒ Object
- #increment_position_by(item, increment) ⇒ Object
- #increment_positions_on_all_items ⇒ Object
-
#increment_positions_on_higher_items(item) ⇒ Object
This has the effect of moving all the higher items down one.
-
#increment_positions_on_lower_items(position) ⇒ Object
This has the effect of moving all the lower items down one.
- #insert_at_position(item, position) ⇒ Object
- #join_table ⇒ Object
- #last?(item) ⇒ Boolean
- #list_item_class ⇒ Object
- #list_item_foreign_key ⇒ Object
- #list_position(item) ⇒ Object
- #lower_item(item) ⇒ Object
- #move_higher(item) ⇒ Object
- #move_lower(item) ⇒ Object
- #move_to_bottom(item) ⇒ Object
- #move_to_position(item, position) ⇒ Object
- #move_to_top(item) ⇒ Object
- #owner ⇒ Object
- #position_column ⇒ Object
-
#remove_from_list(item) ⇒ Object
should only be called externally from the before_remove callback.
-
#reset_positions ⇒ Object
“First aid” method in case someone shifts the array around outside these methods, or the positions in the joins table go totally out of whack.
- #reset_positions_by_ids(ids = self.collect(&:id)) ⇒ Object
-
#resort_array ⇒ Object
called after changing position values so the array reflects the updated ordering.
- #set_position(item, position) ⇒ Object
- #target ⇒ Object
Instance Method Details
#add_to_list_bottom(item) ⇒ Object
181 182 183 184 185 186 187 |
# File 'lib/webpulser-habtm_list.rb', line 181 def add_to_list_bottom(item) item.save! if item.id.nil? # Rails 2.0.2 - Callbacks don't save first on association.create() list_item_class.transaction do assume_bottom_position(item) end resort_array end |
#add_to_list_top(item) ⇒ Object
189 190 191 192 193 194 195 |
# File 'lib/webpulser-habtm_list.rb', line 189 def add_to_list_top(item) list_item_class.transaction do increment_positions_on_all_items assume_top_position(item) end resort_array end |
#assume_bottom_position(item) ⇒ Object
251 252 253 |
# File 'lib/webpulser-habtm_list.rb', line 251 def assume_bottom_position(item) set_position(item, self.length - 1) end |
#assume_top_position(item) ⇒ Object
255 256 257 |
# File 'lib/webpulser-habtm_list.rb', line 255 def assume_top_position(item) set_position(item, 0) end |
#decrement_position(item) ⇒ Object
275 276 277 |
# File 'lib/webpulser-habtm_list.rb', line 275 def decrement_position(item) increment_position_by(item, -1) end |
#decrement_positions_on_higher_items(position) ⇒ Object
This has the effect of moving all the higher items up one.
280 281 282 283 284 285 286 287 288 |
# File 'lib/webpulser-habtm_list.rb', line 280 def decrement_positions_on_higher_items(position) connection.update( "UPDATE #{join_table} SET #{position_column} = (#{position_column} - 1) " + "WHERE #{foreign_key} = #{owner.id} AND #{position_column} <= #{position}" ) target.each { |obj| obj[position_column] = obj[position_column].to_i - 1 if in_list?(obj) && obj[position_column].to_i <= position } if target end |
#decrement_positions_on_lower_items(item) ⇒ Object
This has the effect of moving all the lower items up one.
85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/webpulser-habtm_list.rb', line 85 def decrement_positions_on_lower_items(item) return unless in_list?(item) position = list_position(item) connection.update( "UPDATE #{join_table} SET #{position_column} = (#{position_column} - 1) " + "WHERE #{foreign_key} = #{owner.id} AND #{position_column} > #{position}" ) target.each { |obj| obj[position_column] = obj[position_column].to_i - 1 if in_list?(obj) && obj[position_column].to_i > position } if target end |
#first?(item) ⇒ Boolean
159 160 161 |
# File 'lib/webpulser-habtm_list.rb', line 159 def first?(item) item == self.first end |
#foreign_key ⇒ Object
239 240 241 |
# File 'lib/webpulser-habtm_list.rb', line 239 def foreign_key proxy_association.reflection.primary_key_name end |
#higher_item(item) ⇒ Object
167 168 169 170 |
# File 'lib/webpulser-habtm_list.rb', line 167 def higher_item(item) return nil unless in_list?(item) self.find(:first, :conditions => "#{position_column} = #{(list_position(item) - 1).to_s}") end |
#in_list?(item) ⇒ Boolean
177 178 179 |
# File 'lib/webpulser-habtm_list.rb', line 177 def in_list?(item) self.include?(item) end |
#increment_position(item) ⇒ Object
271 272 273 |
# File 'lib/webpulser-habtm_list.rb', line 271 def increment_position(item) increment_position_by(item, 1) end |
#increment_position_by(item, increment) ⇒ Object
259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/webpulser-habtm_list.rb', line 259 def increment_position_by(item, increment) return unless in_list?(item) connection.update( "UPDATE #{join_table} SET #{position_column} = #{position_column} + (#{increment}) " + "WHERE #{foreign_key} = #{owner.id} AND #{list_item_foreign_key} = #{item.id}" ) if target obj = target.find {|obj| obj.id == item.id} obj[position_column] = obj[position_column].to_i + increment if obj end end |
#increment_positions_on_all_items ⇒ Object
301 302 303 304 305 306 307 308 309 |
# File 'lib/webpulser-habtm_list.rb', line 301 def increment_positions_on_all_items connection.update( "UPDATE #{join_table} SET #{position_column} = (#{position_column} + 1) " + "WHERE #{foreign_key} = #{owner.id}" ) target.each { |obj| obj[position_column] = obj[position_column].to_i + 1 if in_list?(obj) } if target end |
#increment_positions_on_higher_items(item) ⇒ Object
This has the effect of moving all the higher items down one.
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/webpulser-habtm_list.rb', line 98 def increment_positions_on_higher_items(item) return unless in_list?(item) position = list_position(item) connection.update( "UPDATE #{join_table} SET #{position_column} = (#{position_column} + 1) " + "WHERE #{foreign_key} = #{owner.id} AND #{position_column} < #{position}" ) target.each { |obj| obj[position_column] = obj[position_column].to_i + 1 if in_list?(obj) && obj[position_column].to_i < position } if target end |
#increment_positions_on_lower_items(position) ⇒ Object
This has the effect of moving all the lower items down one.
291 292 293 294 295 296 297 298 299 |
# File 'lib/webpulser-habtm_list.rb', line 291 def increment_positions_on_lower_items(position) connection.update( "UPDATE #{join_table} SET #{position_column} = (#{position_column} + 1) " + "WHERE #{foreign_key} = #{owner.id} AND #{position_column} >= #{position}" ) target.each { |obj| obj[position_column] = obj[position_column].to_i + 1 if in_list?(obj) && obj[position_column].to_i >= position } if target end |
#insert_at_position(item, position) ⇒ Object
79 80 81 82 |
# File 'lib/webpulser-habtm_list.rb', line 79 def insert_at_position(item, position) increment_positions_on_lower_items(position) set_position(item, position) end |
#join_table ⇒ Object
235 236 237 |
# File 'lib/webpulser-habtm_list.rb', line 235 def join_table proxy_association.reflection.[:join_table] end |
#last?(item) ⇒ Boolean
163 164 165 |
# File 'lib/webpulser-habtm_list.rb', line 163 def last?(item) item == self.last end |
#list_item_class ⇒ Object
223 224 225 |
# File 'lib/webpulser-habtm_list.rb', line 223 def list_item_class proxy_association.reflection.klass end |
#list_item_foreign_key ⇒ Object
243 244 245 |
# File 'lib/webpulser-habtm_list.rb', line 243 def list_item_foreign_key proxy_association.reflection.association_foreign_key end |
#list_position(item) ⇒ Object
247 248 249 |
# File 'lib/webpulser-habtm_list.rb', line 247 def list_position(item) self.index(item) end |
#lower_item(item) ⇒ Object
172 173 174 175 |
# File 'lib/webpulser-habtm_list.rb', line 172 def lower_item(item) return nil unless in_list?(item) self.find(:first, :conditions => "#{position_column} = #{(list_position(item) + 1).to_s}") end |
#move_higher(item) ⇒ Object
131 132 133 134 135 136 137 138 139 |
# File 'lib/webpulser-habtm_list.rb', line 131 def move_higher(item) list_item_class.transaction do higher = higher_item(item) return unless higher increment_position(higher) decrement_position(item) end resort_array end |
#move_lower(item) ⇒ Object
121 122 123 124 125 126 127 128 129 |
# File 'lib/webpulser-habtm_list.rb', line 121 def move_lower(item) list_item_class.transaction do lower = lower_item(item) return unless lower decrement_position(lower) increment_position(item) end resort_array end |
#move_to_bottom(item) ⇒ Object
141 142 143 144 145 146 147 148 |
# File 'lib/webpulser-habtm_list.rb', line 141 def move_to_bottom(item) return unless in_list?(item) list_item_class.transaction do decrement_positions_on_lower_items(item) assume_bottom_position(item) end resort_array end |
#move_to_position(item, position) ⇒ Object
64 65 66 67 68 69 70 71 72 |
# File 'lib/webpulser-habtm_list.rb', line 64 def move_to_position(item, position) #return if !in_list?(item) || position.to_i == list_position(item) list_item_class.transaction do remove_from_list(item) decrement_positions_on_lower_items(item) insert_at_position(item, position) end resort_array end |
#move_to_top(item) ⇒ Object
150 151 152 153 154 155 156 157 |
# File 'lib/webpulser-habtm_list.rb', line 150 def move_to_top(item) return unless in_list?(item) list_item_class.transaction do increment_positions_on_higher_items(item) assume_top_position(item) end resort_array end |
#owner ⇒ Object
227 228 229 |
# File 'lib/webpulser-habtm_list.rb', line 227 def owner proxy_association.owner end |
#position_column ⇒ Object
219 220 221 |
# File 'lib/webpulser-habtm_list.rb', line 219 def position_column proxy_association.reflection.[:order] || 'position' end |
#remove_from_list(item) ⇒ Object
should only be called externally from the before_remove callback
75 76 77 |
# File 'lib/webpulser-habtm_list.rb', line 75 def remove_from_list(item) item[position_column] = nil end |
#reset_positions ⇒ Object
“First aid” method in case someone shifts the array around outside these methods, or the positions in the joins table go totally out of whack. Don’t use it for simple ordering because it’s inefficient.
200 201 202 203 204 205 206 207 208 |
# File 'lib/webpulser-habtm_list.rb', line 200 def reset_positions self.each_index do |i| item = self[i] connection.update( "UPDATE #{join_table} SET #{position_column} = #{i} " + "WHERE #{foreign_key} = #{owner.id} AND #{list_item_foreign_key} = #{item.id}" ) end end |
#reset_positions_by_ids(ids = self.collect(&:id)) ⇒ Object
210 211 212 213 214 215 216 217 |
# File 'lib/webpulser-habtm_list.rb', line 210 def reset_positions_by_ids(ids = self.collect(&:id)) ids.each_with_index do |id, i| connection.update( "UPDATE #{join_table} SET #{position_column} = #{i} " + "WHERE #{foreign_key} = #{owner.id} AND #{list_item_foreign_key} = #{id}" ) if id.to_i != 0 end end |
#resort_array ⇒ Object
called after changing position values so the array reflects the updated ordering
312 313 314 |
# File 'lib/webpulser-habtm_list.rb', line 312 def resort_array target.sort! {|x,y| x[position_column].to_i <=> y[position_column].to_i} if target end |
#set_position(item, position) ⇒ Object
110 111 112 113 114 115 116 117 118 119 |
# File 'lib/webpulser-habtm_list.rb', line 110 def set_position(item, position) connection.update( "UPDATE #{join_table} SET #{position_column} = #{position} " + "WHERE #{foreign_key} = #{owner.id} AND #{list_item_foreign_key} = #{item.id}" ) if owner.id if target obj = target.find {|obj| obj.id == item.id} obj[position_column] = position if obj end end |
#target ⇒ Object
231 232 233 |
# File 'lib/webpulser-habtm_list.rb', line 231 def target proxy_association.target end |