Module: Mongoid::Tree::Ordering

Extended by:
ActiveSupport::Concern
Defined in:
lib/mongoid/tree/ordering.rb

Overview

Mongoid::Tree::Ordering

Mongoid::Tree doesn't order the tree by default. To enable ordering of children include both Mongoid::Tree and Mongoid::Tree::Ordering into your document.

Utility methods

This module adds methods to get related siblings depending on their position:

node.lower_siblings
node.higher_siblings
node.first_sibling_in_list
node.last_sibling_in_list

There are several methods to move nodes around in the list:

node.move_up
node.move_down
node.move_to_top
node.move_to_bottom
node.move_above(other)
node.move_below(other)

Additionally there are some methods to check aspects of the document in the list of children:

node.at_top?
node.at_bottom?

Instance Method Summary collapse

Instance Method Details

#ancestorsMongoid::Criteria

Returns a chainable criteria for this document's ancestors


49
50
51
# File 'lib/mongoid/tree/ordering.rb', line 49

def ancestors
  base_class.unscoped { super }
end

#at_bottom?Boolean

Is this the lowest sibling?


109
110
111
# File 'lib/mongoid/tree/ordering.rb', line 109

def at_bottom?
  lower_siblings.empty?
end

#at_top?Boolean

Is this the highest sibling?


101
102
103
# File 'lib/mongoid/tree/ordering.rb', line 101

def at_top?
  higher_siblings.empty?
end

#first_sibling_in_listMongoid::Document

Returns the highest sibling (could be self)


93
94
95
# File 'lib/mongoid/tree/ordering.rb', line 93

def first_sibling_in_list
  siblings_and_self.first
end

#higher_siblingsMongoid::Criteria

Returns siblings above the current document. Siblings with a position lower than this document's position.


67
68
69
# File 'lib/mongoid/tree/ordering.rb', line 67

def higher_siblings
  self.siblings.where(:position.lt => self.position)
end

#last_sibling_in_listMongoid::Document

Returns the lowest sibling (could be self)


85
86
87
# File 'lib/mongoid/tree/ordering.rb', line 85

def last_sibling_in_list
  siblings_and_self.last
end

#lower_siblingsMongoid::Criteria

Returns siblings below the current document. Siblings with a position greater than this document's position.


58
59
60
# File 'lib/mongoid/tree/ordering.rb', line 58

def lower_siblings
  self.siblings.where(:position.gt => self.position)
end

#move_above(other) ⇒ undefined

Move this node above the specified node

This method changes the node's parent if nescessary.


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/mongoid/tree/ordering.rb', line 155

def move_above(other)
  ensure_to_be_sibling_of(other)

  if position > other.position
    new_position = other.position
    self.siblings_between(other).inc(:position => 1)
    other.inc(:position => 1)
  else
    new_position = other.position - 1
    self.siblings_between(other).inc(:position => -1)
  end

  self.position = new_position
  save!
end

#move_below(other) ⇒ undefined

Move this node below the specified node

This method changes the node's parent if nescessary.


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/mongoid/tree/ordering.rb', line 179

def move_below(other)
  ensure_to_be_sibling_of(other)

  if position > other.position
    new_position = other.position + 1
    self.siblings_between(other).inc(:position => 1)
  else
    new_position = other.position
    self.siblings_between(other).inc(:position => -1)
    other.inc(:position => -1)
  end

  self.position = new_position
  save!
end

#move_downundefined

Move this node one position down


143
144
145
# File 'lib/mongoid/tree/ordering.rb', line 143

def move_down
  switch_with_sibling_at_offset(1) unless at_bottom?
end

#move_to_bottomundefined

Move this node below all its siblings


126
127
128
129
# File 'lib/mongoid/tree/ordering.rb', line 126

def move_to_bottom
  return true if at_bottom?
  move_below(last_sibling_in_list)
end

#move_to_topundefined

Move this node above all its siblings


117
118
119
120
# File 'lib/mongoid/tree/ordering.rb', line 117

def move_to_top
  return true if at_top?
  move_above(first_sibling_in_list)
end

#move_upundefined

Move this node one position up


135
136
137
# File 'lib/mongoid/tree/ordering.rb', line 135

def move_up
  switch_with_sibling_at_offset(-1) unless at_top?
end

#siblings_between(other) ⇒ Mongoid::Criteria

Returns siblings between the current document and the other document Siblings with a position between this document's position and the other document's position.


76
77
78
79
# File 'lib/mongoid/tree/ordering.rb', line 76

def siblings_between(other)
  range = [self.position, other.position].sort
  self.siblings.where(:position.gt => range.first, :position.lt => range.last)
end