Module: Sortifiable::InstanceMethods
- Defined in:
- lib/sortifiable.rb
Overview
All the methods available to a record that has had acts_as_list specified. Each method works by assuming the object to be the item in the list, so chapter.move_lower would move that chapter lower in the list of all chapters. Likewise, chapter.first? would return true if that chapter is the first in the list of all chapters.
Instance Method Summary collapse
-
#add_to_list ⇒ Object
Add the item to the end of the list.
-
#current_position ⇒ Object
Returns the current position.
-
#decrement_position ⇒ Object
Decrease the position of this item without adjusting the rest of the list.
-
#first? ⇒ Boolean
(also: #top?)
Return
trueif this object is the first in the list. -
#first_item ⇒ Object
(also: #top_item)
Returns the first item in the list.
-
#higher_item ⇒ Object
(also: #previous_item)
Return the next higher item in the list.
-
#higher_items ⇒ Object
Return items lower than this item or an empty array if it is the last item.
-
#in_list? ⇒ Boolean
Test if this record is in a list.
-
#increment_position ⇒ Object
Increase the position of this item without adjusting the rest of the list.
-
#insert_at(position = 1) ⇒ Object
Insert the item at the given position (defaults to the top position of 1).
-
#item_at_offset(offset) ⇒ Object
Return the item at the offset specified from the current position.
-
#last? ⇒ Boolean
(also: #bottom?)
Return
trueif this object is the last in the list. -
#last_item ⇒ Object
(also: #bottom_item)
Returns the bottom item.
-
#last_position ⇒ Object
(also: #bottom_position)
Returns the bottom position in the list.
-
#lower_item ⇒ Object
(also: #next_item)
Return the next lower item in the list.
-
#lower_items ⇒ Object
Return items lower than this item or an empty array if it is the last item.
-
#move_higher ⇒ Object
(also: #move_up)
Swap positions with the next higher item, if one exists.
-
#move_lower ⇒ Object
(also: #move_down)
Swap positions with the next lower item, if one exists.
-
#move_to_bottom ⇒ Object
Move to the bottom of the list.
-
#move_to_top ⇒ Object
Move to the top of the list.
-
#remove_from_list ⇒ Object
Removes the item from the list.
-
#will_leave_list? ⇒ Boolean
Test if this record is in a scoped list but will leave the scoped list when saved.
Instance Method Details
#add_to_list ⇒ Object
Add the item to the end of the list
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/sortifiable.rb', line 104 def add_to_list if in_list? move_to_bottom else list_class.transaction do ids = lock_list! last_position = ids.size if persisted? update_position last_position + 1 else set_position last_position + 1 end end end end |
#current_position ⇒ Object
Returns the current position
121 122 123 |
# File 'lib/sortifiable.rb', line 121 def current_position send(position_column).to_i end |
#decrement_position ⇒ Object
Decrease the position of this item without adjusting the rest of the list.
126 127 128 |
# File 'lib/sortifiable.rb', line 126 def decrement_position in_list? && update_position(current_position - 1) end |
#first? ⇒ Boolean Also known as: top?
Return true if this object is the first in the list.
131 132 133 |
# File 'lib/sortifiable.rb', line 131 def first? in_list? && current_position == 1 end |
#first_item ⇒ Object Also known as: top_item
Returns the first item in the list
137 138 139 |
# File 'lib/sortifiable.rb', line 137 def first_item list_scope.first end |
#higher_item ⇒ Object Also known as: previous_item
Return the next higher item in the list.
143 144 145 |
# File 'lib/sortifiable.rb', line 143 def higher_item item_at_offset(-1) end |
#higher_items ⇒ Object
Return items lower than this item or an empty array if it is the last item
149 150 151 |
# File 'lib/sortifiable.rb', line 149 def higher_items list_scope.where(["#{quoted_position_column} < ?", current_position]).to_a end |
#in_list? ⇒ Boolean
Test if this record is in a list
154 155 156 |
# File 'lib/sortifiable.rb', line 154 def in_list? !new_record? && !send(position_column).nil? end |
#increment_position ⇒ Object
Increase the position of this item without adjusting the rest of the list.
164 165 166 |
# File 'lib/sortifiable.rb', line 164 def increment_position in_list? && update_position(current_position + 1) end |
#insert_at(position = 1) ⇒ Object
Insert the item at the given position (defaults to the top position of 1).
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/sortifiable.rb', line 169 def insert_at(position = 1) list_class.transaction do ids = lock_list! position = [[1, position].max, ids.size].min if persisted? current_position = ids.index(id) + 1 sql = <<-SQL #{quoted_position_column} = CASE WHEN #{quoted_position_column} = #{current_position} THEN #{position} WHEN #{quoted_position_column} > #{current_position} AND #{quoted_position_column} <= #{position} THEN #{quoted_position_column} - 1 WHEN #{quoted_position_column} < #{current_position} AND #{quoted_position_column} >= #{position} THEN #{quoted_position_column} + 1 ELSE #{quoted_position_column} END SQL list_scope.update_all(sql) update_position(position) else save! sql = <<-SQL #{quoted_position_column} = CASE WHEN #{quoted_position_column} >= #{position} THEN #{quoted_position_column} + 1 ELSE #{quoted_position_column} END SQL list_scope.update_all(sql) update_position(position) end end end |
#item_at_offset(offset) ⇒ Object
Return the item at the offset specified from the current position
207 208 209 |
# File 'lib/sortifiable.rb', line 207 def item_at_offset(offset) in_list? ? offset_scope(offset).first : nil end |
#last? ⇒ Boolean Also known as: bottom?
Return true if this object is the last in the list.
212 213 214 |
# File 'lib/sortifiable.rb', line 212 def last? in_list? && current_position == last_position end |
#last_item ⇒ Object Also known as: bottom_item
Returns the bottom item
218 219 220 |
# File 'lib/sortifiable.rb', line 218 def last_item list_scope.last end |
#last_position ⇒ Object Also known as: bottom_position
Returns the bottom position in the list.
224 225 226 |
# File 'lib/sortifiable.rb', line 224 def last_position last_item.try(:current_position) || 0 end |
#lower_item ⇒ Object Also known as: next_item
Return the next lower item in the list.
230 231 232 |
# File 'lib/sortifiable.rb', line 230 def lower_item item_at_offset(1) end |
#lower_items ⇒ Object
Return items lower than this item or an empty array if it is the last item
236 237 238 |
# File 'lib/sortifiable.rb', line 236 def lower_items list_scope.where(["#{quoted_position_column} > ?", current_position]).to_a end |
#move_higher ⇒ Object Also known as: move_up
Swap positions with the next higher item, if one exists.
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/sortifiable.rb', line 241 def move_higher if in_list? list_class.transaction do ids = lock_list! current_position = ids.index(id) + 1 if current_position > 1 sql = <<-SQL #{quoted_position_column} = CASE WHEN #{quoted_position_column} = #{current_position} - 1 THEN #{current_position} WHEN #{quoted_position_column} = #{current_position} THEN #{current_position} - 1 ELSE #{quoted_position_column} END SQL set_position current_position - 1 list_scope.update_all(sql) > 0 else true end end else false end end |
#move_lower ⇒ Object Also known as: move_down
Swap positions with the next lower item, if one exists.
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/sortifiable.rb', line 269 def move_lower if in_list? list_class.transaction do ids = lock_list! current_position, last_position = ids.index(id) + 1, ids.size if current_position < last_position sql = <<-SQL #{quoted_position_column} = CASE WHEN #{quoted_position_column} = #{current_position} + 1 THEN #{current_position} WHEN #{quoted_position_column} = #{current_position} THEN #{current_position} + 1 ELSE #{quoted_position_column} END SQL set_position current_position + 1 list_scope.update_all(sql) > 0 else true end end else false end end |
#move_to_bottom ⇒ Object
Move to the bottom of the list. If the item is already in the list, the items below it have their position adjusted accordingly.
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/sortifiable.rb', line 298 def move_to_bottom if in_list? list_class.transaction do ids = lock_list! current_position, last_position = ids.index(id) + 1, ids.size if current_position < last_position sql = <<-SQL #{quoted_position_column} = CASE WHEN #{quoted_position_column} = #{current_position} THEN #{last_position} WHEN #{quoted_position_column} > #{current_position} THEN #{quoted_position_column} - 1 ELSE #{quoted_position_column} END SQL set_position last_position list_scope.update_all(sql) > 0 else true end end else false end end |
#move_to_top ⇒ Object
Move to the top of the list. If the item is already in the list, the items above it have their position adjusted accordingly.
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/sortifiable.rb', line 326 def move_to_top if in_list? list_class.transaction do ids = lock_list! current_position = ids.index(id) + 1 if current_position > 1 sql = <<-SQL #{quoted_position_column} = CASE WHEN #{quoted_position_column} = #{current_position} THEN 1 WHEN #{quoted_position_column} < #{current_position} THEN #{quoted_position_column} + 1 ELSE #{quoted_position_column} END SQL set_position 1 list_scope.update_all(sql) > 0 else true end end else false end end |
#remove_from_list ⇒ Object
Removes the item from the list.
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 |
# File 'lib/sortifiable.rb', line 353 def remove_from_list if in_list? list_class.transaction do ids = lock_list! current_position = ids.index(id) + 1 sql = <<-SQL #{quoted_position_column} = CASE WHEN #{quoted_position_column} = #{current_position} THEN NULL WHEN #{quoted_position_column} > #{current_position} THEN #{quoted_position_column} - 1 ELSE #{quoted_position_column} END SQL set_position nil list_scope.update_all(sql) > 0 end else false end end |
#will_leave_list? ⇒ Boolean
Test if this record is in a scoped list but will leave the scoped list when saved
159 160 161 |
# File 'lib/sortifiable.rb', line 159 def will_leave_list? in_list? && scope_parts.any? { |scope_part| send("#{scope_part}_changed?") } end |