Module: MongoMapper::Plugins::ReferencedTree::InstanceMethods

Defined in:
lib/mm-referenced-tree.rb

Instance Method Summary collapse

Instance Method Details

#ancestorsObject



151
152
153
154
# File 'lib/mm-referenced-tree.rb', line 151

def ancestors
  return if root?
  scoped_find.all(:depth => {:"$lt" => depth}, :"reference.0" => reference[0])
end

#childrenObject



185
186
187
188
189
# File 'lib/mm-referenced-tree.rb', line 185

def children
  query         = query_for_reference(reference[0, depth])
  query[:depth] = depth + 1
  scoped_find.all(query)
end

#descendantsObject



191
192
193
194
195
# File 'lib/mm-referenced-tree.rb', line 191

def descendants
  query         = query_for_reference(reference[0, depth])
  query[:depth] = {:"$gt" => depth}
  scoped_find.all(query)
end

#destroyObject

removes this node and renumbers siblings and descendants



74
75
76
# File 'lib/mm-referenced-tree.rb', line 74

def destroy
  super
end

#destroy_with_childrenObject

removes this node and all descendants, renumbers siblings



79
80
81
82
# File 'lib/mm-referenced-tree.rb', line 79

def destroy_with_children
  @destroy_descendants = true
  destroy
end

#formatted_referenceObject

Provides a formatted version of the reference

1,2,3

> “1.2.3”

override this in your model if you want to format the references differently



89
90
91
# File 'lib/mm-referenced-tree.rb', line 89

def formatted_reference
  reference.join(".")
end

#indentObject

TODO - implement this increases the depth of the node if possible can’t indent if there’s nothing before it on the same level (to become the new parent)



109
110
# File 'lib/mm-referenced-tree.rb', line 109

def indent
end

#is_ancestor_of?(other) ⇒ Boolean

Returns:

  • (Boolean)


201
202
203
204
# File 'lib/mm-referenced-tree.rb', line 201

def is_ancestor_of?(other)
  return false if other.depth <= depth
  other.reference[0, depth] == reference
end

#is_descendant_of?(other) ⇒ Boolean

Returns:

  • (Boolean)


210
211
212
213
# File 'lib/mm-referenced-tree.rb', line 210

def is_descendant_of?(other)
  return false if other.depth >= depth
  reference[0, other.depth] == other.reference
end

#is_or_is_ancestor_of?(other) ⇒ Boolean

Returns:

  • (Boolean)


206
207
208
# File 'lib/mm-referenced-tree.rb', line 206

def is_or_is_ancestor_of?(other)
  other == self || is_ancestor_of?(other)
end

#is_or_is_descendant_of?(other) ⇒ Boolean

Returns:

  • (Boolean)


215
216
217
# File 'lib/mm-referenced-tree.rb', line 215

def is_or_is_descendant_of?(other)
  other == self || is_descendant_of?(other)
end

#is_or_is_sibling_of?(other) ⇒ Boolean

Returns:

  • (Boolean)


224
225
226
# File 'lib/mm-referenced-tree.rb', line 224

def is_or_is_sibling_of?(other)
  other == self || is_sibling_of?(other)
end

#is_sibling_of?(other) ⇒ Boolean

Returns:

  • (Boolean)


219
220
221
222
# File 'lib/mm-referenced-tree.rb', line 219

def is_sibling_of?(other)
  return false if other.depth != depth
  reference[0, depth-1] == other.reference[0, depth-1]
end

#next_siblingsObject



171
172
173
174
175
176
177
# File 'lib/mm-referenced-tree.rb', line 171

def next_siblings
  query = query_for_reference(reference[0, depth-1])
  query[:"reference.#{depth-1}"] = {:"$gt" => reference.last - 1}
  query[:depth] = depth
  query[:id] = {:"$ne" => self.id}
  scoped_find.all(query)
end

#outdentObject

TODO - implement this decreases the depth of the node if possible can’t outdent further than 1



115
116
# File 'lib/mm-referenced-tree.rb', line 115

def outdent
end

#parentObject

returns the parent for the node so [1,2,3] would look for a node with reference of [1,2]



120
121
122
123
124
125
# File 'lib/mm-referenced-tree.rb', line 120

def parent
  return if root?
  query         = query_for_reference(reference[0, depth-1])
  query[:depth] = depth - 1
  scoped_find.first(query)
end

#parent=(obj) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
# File 'lib/mm-referenced-tree.rb', line 127

def parent=(obj)
  ref = obj.reference

  if child = obj.children.last
    ref << (child.reference.last + 1)
  else
    ref << 1
  end

  self.reference = ref
end

#previous_siblingsObject



163
164
165
166
167
168
169
# File 'lib/mm-referenced-tree.rb', line 163

def previous_siblings
  query = query_for_reference(reference[0, depth-1])
  query[:"reference.#{depth-1}"] = {:"$lt" => reference.last + 1}
  query[:depth] = depth
  query[:id] = {:"$ne" => self.id}
  scoped_find.all(query)
end

#reference=(ref) ⇒ Object



93
94
95
96
# File 'lib/mm-referenced-tree.rb', line 93

def reference=(ref)
  self.depth = ref.size
  super
end

#rootObject



143
144
145
# File 'lib/mm-referenced-tree.rb', line 143

def root
  scoped_find.first(:"reference.0" => reference[0], :depth => 1)
end

#root?Boolean

Returns:

  • (Boolean)


139
140
141
# File 'lib/mm-referenced-tree.rb', line 139

def root?
  depth == 1
end

#rootsObject



147
148
149
# File 'lib/mm-referenced-tree.rb', line 147

def roots
  scoped_find.all(:depth => 1)
end

#self_and_descendantsObject



197
198
199
# File 'lib/mm-referenced-tree.rb', line 197

def self_and_descendants
  [self] + descendants
end

#self_and_siblingsObject



179
180
181
182
183
# File 'lib/mm-referenced-tree.rb', line 179

def self_and_siblings
  query         = query_for_reference(reference[0, depth-1])
  query[:depth] = depth
  scoped_find.all(query)
end

#set_reference(ref) ⇒ Object

set the reference without calling #save, so no callbacks are triggered good for renumbering on mass without triggering auto-renumbering but may end up with the tree being out of sync if you don’t reorder all nodes



101
102
103
104
# File 'lib/mm-referenced-tree.rb', line 101

def set_reference(ref)
  self.reference = ref
  set(:reference => ref, :depth => depth)
end

#siblingsObject



156
157
158
159
160
161
# File 'lib/mm-referenced-tree.rb', line 156

def siblings
  query         = query_for_reference(reference[0, depth-1])
  query[:depth] = depth
  query[:id]    = {:"$ne" => self.id}
  scoped_find.all(query)
end