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

#ancestorsObject

Returns a chainable criteria for this document’s ancestors



47
48
49
# File 'lib/mongoid/tree/ordering.rb', line 47

def ancestors
  base_class.unscoped.where(:_id.in => parent_ids)
end

#at_bottom?Boolean

Is this the lowest sibling?

Returns:

  • (Boolean)


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

def at_bottom?
  lower_siblings.empty?
end

#at_top?Boolean

Is this the highest sibling?

Returns:

  • (Boolean)


79
80
81
# File 'lib/mongoid/tree/ordering.rb', line 79

def at_top?
  higher_siblings.empty?
end

#first_sibling_in_listObject

Returns the highest sibling (could be self)



73
74
75
# File 'lib/mongoid/tree/ordering.rb', line 73

def first_sibling_in_list
  siblings_and_self.first
end

#higher_siblingsObject

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



61
62
63
# File 'lib/mongoid/tree/ordering.rb', line 61

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

#last_sibling_in_listObject

Returns the lowest sibling (could be self)



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

def last_sibling_in_list
  siblings_and_self.last
end

#lower_siblingsObject

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



54
55
56
# File 'lib/mongoid/tree/ordering.rb', line 54

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

#move_above(other) ⇒ Object

Move this node above the specified node

This method changes the node’s parent if nescessary.



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/mongoid/tree/ordering.rb', line 123

def move_above(other)
  unless sibling_of?(other)
    self.parent_id = other.parent_id
    save!
  end

  if position > other.position
    new_position = other.position
    other.lower_siblings.where(:position.lt => self.position).each { |s| s.inc(:position, 1) }
    other.inc(:position, 1)
    self.position = new_position
    save!
  else
    new_position = other.position - 1
    other.higher_siblings.where(:position.gt => self.position).each { |s| s.inc(:position, -1) }
    self.position = new_position
    save!
  end
end

#move_below(other) ⇒ Object

Move this node below the specified node

This method changes the node’s parent if nescessary.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/mongoid/tree/ordering.rb', line 147

def move_below(other)
  unless sibling_of?(other)
    self.parent_id = other.parent_id
    save!
  end

  if position > other.position
    new_position = other.position + 1
    other.lower_siblings.where(:position.lt => self.position).each { |s| s.inc(:position, 1) }
    self.position = new_position
    save!
  else
    new_position = other.position
    other.higher_siblings.where(:position.gt => self.position).each { |s| s.inc(:position, -1) }
    other.inc(:position, -1)
    self.position = new_position
    save!
  end
end

#move_downObject

Move this node one position down



113
114
115
116
117
# File 'lib/mongoid/tree/ordering.rb', line 113

def move_down
  return if at_bottom?
  siblings.where(:position => self.position + 1).first.inc(:position, -1)
  inc(:position, 1)
end

#move_to_bottomObject

Move this node below all its siblings



98
99
100
101
# File 'lib/mongoid/tree/ordering.rb', line 98

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

#move_to_topObject

Move this node above all its siblings



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

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

#move_upObject

Move this node one position up



105
106
107
108
109
# File 'lib/mongoid/tree/ordering.rb', line 105

def move_up
  return if at_top?
  siblings.where(:position => self.position - 1).first.inc(:position, 1)
  inc(:position, -1)
end