module Mongestry::InstanceMethods

Public Class Methods

included(base) click to toggle source
# File lib/mongestry.rb, line 15
def self.included base
  base.extend Mongestry::ClassMethods
end

Public Instance Methods

ancestor_ids() click to toggle source

Returns a list of ancestor ids, starting with the root id and ending with the parent id

# File lib/mongestry.rb, line 34
def ancestor_ids
  self.ancestry.split('/').collect{ |s| BSON::ObjectId.from_string s }
end
ancestors() click to toggle source

Scopes the model on ancestors of the record

# File lib/mongestry.rb, line 39
def ancestors
  return [] if self.is_root?
  self.class.where(_id: {"$in" => self.ancestor_ids})
end
build_ancestry() click to toggle source
# File lib/mongestry.rb, line 19
def build_ancestry
  raise "Either parent or parent_id can be given, not both at once" if self.attributes.keys.include?("parent") and self.attributes.keys.include?("parent_id")
  return unless self.respond_to?(:parent) or self.respond_to?(:parent_id)

  parent = self.class.object_for(self.attributes["parent"] || self.attributes["parent_id"])

  self.ancestry = nil unless parent
  self.ancestry = parent.ancestry.nil? ? parent.id.to_s : parent.ancestry.to_s + "/#{parent.id.to_s}" if parent
  self.persisted_depth = parent.depth + 1 rescue 0

  self.attributes.delete("parent")
  self.attributes.delete("parent_id")
end
child_ids() click to toggle source

Returns a list of child ids

# File lib/mongestry.rb, line 81
def child_ids
  self.children.map(&:id)
end
children() click to toggle source

Scopes the model on children of the record

# File lib/mongestry.rb, line 71
def children
  case self.is_root?
  when true
    self.class.where(:ancestry => self.ancestry.to_s + "#{self.id.to_s}")
  else
    self.class.where(:ancestry => self.ancestry.to_s + "/#{self.id.to_s}")
  end
end
depth() click to toggle source

Return the depth of the node, root nodes are at depth 0

# File lib/mongestry.rb, line 137
def depth
  self.ancestry.split('/').size rescue 0
end
descendant_ids() click to toggle source

Returns a list of a descendant ids

# File lib/mongestry.rb, line 122
def descendant_ids
  self.descendants.map(&:id)
end
descendants() click to toggle source

Scopes the model on direct and indirect children of the record

# File lib/mongestry.rb, line 116
def descendants
  expression = self.is_root? ? self.id.to_s : (self.ancestry + "/#{self.id.to_s}").split('/').join('\/')
  self.class.where(:ancestry => Regexp.new(expression))
end
has_children?() click to toggle source

Returns true if the record has any children, false otherwise

# File lib/mongestry.rb, line 86
def has_children?
  !self.children.to_a.blank?
end
has_siblings?() click to toggle source

Returns true if the record’s parent has more than one child

# File lib/mongestry.rb, line 106
def has_siblings?
  self.siblings.present?
end
is_childless?() click to toggle source

Returns true if the record has no childen, false otherwise

# File lib/mongestry.rb, line 91
def is_childless?
  !self.has_children?
end
is_only_child?() click to toggle source

Returns true if the record is the only child of its parent

# File lib/mongestry.rb, line 111
def is_only_child?
  !self.has_siblings?
end
is_root?() click to toggle source

Returns true if the record is a root node, false otherwise

# File lib/mongestry.rb, line 66
def is_root?
  self.ancestry.nil?
end
parent() click to toggle source

Returns the parent of the record, nil for a root node

# File lib/mongestry.rb, line 45
def parent
  self.class.where(_id: self.ancestry.split('/').last).first rescue nil
end
parent_id() click to toggle source

Returns the id of the parent of the record, nil for a root node

# File lib/mongestry.rb, line 50
def parent_id
  self.parent.id rescue nil
end
root() click to toggle source

Returns the root of the tree the record is in, self for a root node

# File lib/mongestry.rb, line 55
def root
  return self unless self.ancestry
  self.class.where(_id: self.ancestry.split('/').first).first
end
root_id() click to toggle source

Returns the id of the root of the tree the record is in

# File lib/mongestry.rb, line 61
def root_id
  self.root.id
end
sibling_ids() click to toggle source

Returns a list of sibling ids

# File lib/mongestry.rb, line 101
def sibling_ids
  self.siblings.map(&:id)
end
siblings() click to toggle source

Scopes the model on siblings of the record, the record itself is included

# File lib/mongestry.rb, line 96
def siblings
  self.class.where(:ancestry => self.ancestry.to_s).and(:_id => {'$ne' => self.id})
end
subtree() click to toggle source

Scopes the model on descendants and itself

# File lib/mongestry.rb, line 127
def subtree
  self.class.where(_id: {"$in" => self.descendant_ids.push(self.id)})
end
subtree_ids() click to toggle source

Returns a list of all ids in the record’s subtree

# File lib/mongestry.rb, line 132
def subtree_ids
  self.subtree.map(&:id)
end