module CollectiveIdea::Acts::NestedSet::Model::Movable

Public Instance Methods

find_left_neighbor(parent, order_attribute, ascending) click to toggle source

Find the node immediately to the left of this node.

# File lib/awesome_nested_set/model/movable.rb, line 87
def find_left_neighbor(parent, order_attribute, ascending)
  left = nil
  parent.children.each do |n|
    if ascending
      left = n if n.send(order_attribute) < self.send(order_attribute)
    else
      left = n if n.send(order_attribute) > self.send(order_attribute)
    end
  end
  left
end
move_left() click to toggle source

Shorthand method for finding the left sibling and moving to the left of it.

# File lib/awesome_nested_set/model/movable.rb, line 18
def move_left
  move_to_left_of left_sibling
end
move_possible?(target) click to toggle source
# File lib/awesome_nested_set/model/movable.rb, line 9
def move_possible?(target)
  self != target && # Can't target self
    same_scope?(target) && # can't be in different scopes
    # detect impossible move
    within_bounds?(target.left, target.left) &&
    within_bounds?(target.right, target.right)
end
move_right() click to toggle source

Shorthand method for finding the right sibling and moving to the right of it.

# File lib/awesome_nested_set/model/movable.rb, line 23
def move_right
  move_to_right_of right_sibling
end
move_to(target, position) click to toggle source
# File lib/awesome_nested_set/model/movable.rb, line 99
def move_to(target, position)
  prevent_unpersisted_move

  run_callbacks :move do
    in_tenacious_transaction do
      target = reload_target(target, position)
      self.reload_nested_set

      Move.new(target, position, self).move
    end
    after_move_to(target, position)
  end
end
move_to_child_of(node) click to toggle source

Move the node to the child of another node

# File lib/awesome_nested_set/model/movable.rb, line 38
def move_to_child_of(node)
  move_to node, :child
end
move_to_child_with_index(node, index) click to toggle source

Move the node to the child of another node with specify index

# File lib/awesome_nested_set/model/movable.rb, line 43
def move_to_child_with_index(node, index)
  if node.children.empty?
    move_to_child_of(node)
  elsif node.children.count == index
    move_to_right_of(node.children.last)
  else
    my_position = node.children.index(self)
    if my_position && my_position < index
      # e.g. if self is at position 0 and we want to move self to position 1 then self
      # needs to move to the *right* of the node at position 1. That's because the node
      # that is currently at position 1 will be at position 0 after the move completes.
      move_to_right_of(node.children[index])
    elsif my_position && my_position == index
      # do nothing. already there.
    else
      move_to_left_of(node.children[index])
    end
  end
end
move_to_left_of(node) click to toggle source

Move the node to the left of another node

# File lib/awesome_nested_set/model/movable.rb, line 28
def move_to_left_of(node)
  move_to node, :left
end
move_to_ordered_child_of(parent, order_attribute, ascending = true) click to toggle source

Order children in a nested set by an attribute Can order by any attribute class that uses the Comparable mixin, for example a string or integer Usage example when sorting categories alphabetically: @new_category.move_to_ordered_child_of(@root, “name”)

# File lib/awesome_nested_set/model/movable.rb, line 71
def move_to_ordered_child_of(parent, order_attribute, ascending = true)
  self.move_to_root and return unless parent

  left_neighbor = find_left_neighbor(parent, order_attribute, ascending)
  self.move_to_child_of(parent)

  return unless parent.children.many?

  if left_neighbor
    self.move_to_right_of(left_neighbor)
  else # Self is the left most node.
    self.move_to_left_of(parent.children[0])
  end
end
move_to_right_of(node) click to toggle source

Move the node to the right of another node

# File lib/awesome_nested_set/model/movable.rb, line 33
def move_to_right_of(node)
  move_to node, :right
end
move_to_root() click to toggle source

Move the node to root nodes

# File lib/awesome_nested_set/model/movable.rb, line 64
def move_to_root
  move_to self, :root
end

Protected Instance Methods

after_move_to(target, position) click to toggle source
# File lib/awesome_nested_set/model/movable.rb, line 115
def after_move_to(target, position)
  target.reload_nested_set if target
  self.set_depth_for_self_and_descendants!
  self.reload_nested_set
end
move_to_new_parent() click to toggle source
# File lib/awesome_nested_set/model/movable.rb, line 121
def move_to_new_parent
  if @move_to_new_parent_id.nil?
    move_to_root
  elsif @move_to_new_parent_id
    move_to_child_of(@move_to_new_parent_id)
  end
end
out_of_bounds?(left_bound, right_bound) click to toggle source
# File lib/awesome_nested_set/model/movable.rb, line 129
def out_of_bounds?(left_bound, right_bound)
  left <= left_bound && right >= right_bound
end
prevent_unpersisted_move() click to toggle source
# File lib/awesome_nested_set/model/movable.rb, line 133
def prevent_unpersisted_move
  if self.new_record?
    raise ActiveRecord::ActiveRecordError, "You cannot move a new node"
  end
end
within_bounds?(left_bound, right_bound) click to toggle source
# File lib/awesome_nested_set/model/movable.rb, line 139
def within_bounds?(left_bound, right_bound)
  !out_of_bounds?(left_bound, right_bound)
end