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

Returns:

  • (Mongoid::Criteria)

    Mongoid criteria to retrieve the 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?

Returns:

  • (Boolean)

    Whether the document is 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?

Returns:

  • (Boolean)

    Whether the document is 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)

Returns:

  • (Mongoid::Document)

    The highest sibling


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.

Returns:

  • (Mongoid::Criteria)

    Mongoid criteria to retrieve the document's higher siblings


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)

Returns:

  • (Mongoid::Document)

    The lowest sibling


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.

Returns:

  • (Mongoid::Criteria)

    Mongoid criteria to retrieve the document's lower siblings


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.

Parameters:

Returns:

  • (undefined)

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.

Parameters:

Returns:

  • (undefined)

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

Returns:

  • (undefined)

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

Returns:

  • (undefined)

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

Returns:

  • (undefined)

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

Returns:

  • (undefined)

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.

Returns:

  • (Mongoid::Criteria)

    Mongoid criteria to retrieve the documents between this and the other document


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