Module: CollectiveIdea::Acts::NestedSet::Model::Movable

Defined in:
lib/awesome_nested_set/model/movable.rb

Instance Method Summary collapse

Instance Method Details

#find_left_neighbor(parent, order_attribute, ascending) ⇒ Object

Find the node immediately to the left of this node.



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/awesome_nested_set/model/movable.rb', line 92

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_leftObject

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



18
19
20
# File 'lib/awesome_nested_set/model/movable.rb', line 18

def move_left
  move_to_left_of left_sibling
end

#move_possible?(target) ⇒ Boolean

Returns:

  • (Boolean)


9
10
11
12
13
14
15
# 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_rightObject

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



23
24
25
# File 'lib/awesome_nested_set/model/movable.rb', line 23

def move_right
  move_to_right_of right_sibling
end

#move_to(target, position) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/awesome_nested_set/model/movable.rb', line 104

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
      update_counter_cache
    end
    after_move_to(target, position)
  end
end

#move_to_child_of(node) ⇒ Object

Move the node to the child of another node



38
39
40
41
42
43
44
# File 'lib/awesome_nested_set/model/movable.rb', line 38

def move_to_child_of(node)
  if node == :root
    move_to_root
  else
    move_to node, :child
  end
end

#move_to_child_with_index(node, index) ⇒ Object

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



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/awesome_nested_set/model/movable.rb', line 47

def move_to_child_with_index(node, index)
  siblings = node == :root ? roots : node.children
  if siblings.empty?
    move_to_child_of(node)
  elsif siblings.count == index
    move_to_right_of(siblings.last)
  else
    my_position = siblings.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(siblings[index])
    elsif my_position && my_position == index
      # do nothing. already there.
    else
      move_to_left_of(siblings[index])
    end
  end
end

#move_to_left_of(node) ⇒ Object

Move the node to the left of another node



28
29
30
# 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) ⇒ Object

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”)



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/awesome_nested_set/model/movable.rb', line 76

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) ⇒ Object

Move the node to the right of another node



33
34
35
# File 'lib/awesome_nested_set/model/movable.rb', line 33

def move_to_right_of(node)
  move_to node, :right
end

#move_to_rootObject

Move the node to root nodes



69
70
71
# File 'lib/awesome_nested_set/model/movable.rb', line 69

def move_to_root
  move_to self, :root
end