module OrderedTree::InstanceMethods::List
Public Instance Methods
move_above(sibling = nil)
click to toggle source
moves the item above sibling in the list
defaults to the top of the list
# File lib/ordered_tree/instance_methods/list.rb, line 35 def move_above(sibling = nil) if sibling return if (!self_and_siblings(true).include?(sibling) || (sibling == self)) if sibling.position_in_list > position_in_list move_to(sibling.position_in_list - 1) else move_to(sibling.position_in_list) end else move_to_top end end
move_higher()
click to toggle source
swap with the node above self
# File lib/ordered_tree/instance_methods/list.rb, line 55 def move_higher return if position_in_list == 1 move_to(position_in_list - 1) end
move_lower()
click to toggle source
swap with the node below self
# File lib/ordered_tree/instance_methods/list.rb, line 61 def move_lower return if self == self_and_siblings(true).last move_to(position_in_list + 1) end
move_to_bottom()
click to toggle source
move to the bottom of the list
# File lib/ordered_tree/instance_methods/list.rb, line 67 def move_to_bottom return if self == self_and_siblings(true).last move_to(self_and_siblings.last.position_in_list) end
move_to_top()
click to toggle source
move to the top of the list
# File lib/ordered_tree/instance_methods/list.rb, line 49 def move_to_top return if position_in_list == 1 move_to(1) end
position_in_list()
click to toggle source
returns object’s position in the list
the list will either be parent.children, or self.class.roots i.e. self.position
# File lib/ordered_tree/instance_methods/list.rb, line 27 def position_in_list self[order_column] end
self_and_siblings(reload = false)
click to toggle source
returns an array of the object’s siblings, including itself
return is cached use self_and_siblings(true) to force a reload
# File lib/ordered_tree/instance_methods/list.rb, line 10 def self_and_siblings(reload = false) parent(reload) ? parent.children(reload) : self.class.roots(scope_condition) end
siblings(reload = false)
click to toggle source
returns an array of the object’s siblings, excluding itself
return is cached use siblings(true) to force a reload
# File lib/ordered_tree/instance_methods/list.rb, line 18 def siblings(reload = false) self_and_siblings(reload) - [self] end
Private Instance Methods
add_to_list()
click to toggle source
# File lib/ordered_tree/instance_methods/list.rb, line 99 def add_to_list new_position = position_in_list if (1..self_and_siblings(true).size).include?(position_in_list.to_i) add_to_list_bottom move_to(new_position, true) if new_position end
add_to_list_bottom()
click to toggle source
# File lib/ordered_tree/instance_methods/list.rb, line 105 def add_to_list_bottom self[order_column] = self_and_siblings.size + 1 end
move_to(new_position, on_create = false)
click to toggle source
# File lib/ordered_tree/instance_methods/list.rb, line 109 def move_to(new_position, on_create = false) if parent(true) scope = "#{foreign_key_column} = #{parent.id}" else scope = "#{foreign_key_column} = 0" end if new_position < position_in_list # moving from lower to higher, increment all in between # #{order_column} >= #{new_position} AND #{order_column} < #{position_in_list} self.class.transaction do self.class.#where(order_column => order_column + 1). where(scope). where("#{order_column} BETWEEN #{new_position} AND #{position_in_list - 1}"). update_all("#{order_column} = (#{order_column} + 1)") if on_create self[order_column] = new_position else update_attribute(order_column, new_position) end end else # moving from higher to lower, decrement all in between # #{order_column} > #{position_in_list} AND #{order_column} <= #{new_position} self.class.transaction do self.class.where(scope). where("#{order_column} BETWEEN #{position_in_list + 1} AND #{new_position}"). update_all("#{order_column} = (#{order_column} - 1)") update_attribute(order_column, new_position) end end end
reorder_roots()
click to toggle source
# File lib/ordered_tree/instance_methods/list.rb, line 141 def reorder_roots self.class.transaction do self.class.roots(scope_condition).each do |root| new_position = self.class.roots(scope_condition).index(root) + 1 root.update_attribute(order_column, new_position) if (root.position_in_list != new_position) end end end