Module: Mongestry::InstanceMethods

Defined in:
lib/mongestry.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



15
16
17
# File 'lib/mongestry.rb', line 15

def self.included base
  base.extend Mongestry::ClassMethods
end

Instance Method Details

#ancestor_idsObject

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



34
35
36
# File 'lib/mongestry.rb', line 34

def ancestor_ids
  self.ancestry.split('/').collect{ |s| BSON::ObjectId.from_string s }
end

#ancestorsObject

Scopes the model on ancestors of the record



39
40
41
42
# File 'lib/mongestry.rb', line 39

def ancestors
  return [] if self.is_root?
  self.class.where(_id: {"$in" => self.ancestor_ids})
end

#build_ancestryObject



19
20
21
22
23
24
25
26
27
28
29
30
31
# 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_idsObject

Returns a list of child ids



81
82
83
# File 'lib/mongestry.rb', line 81

def child_ids
  self.children.map(&:id)
end

#childrenObject

Scopes the model on children of the record



71
72
73
74
75
76
77
78
# 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

#depthObject

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



137
138
139
# File 'lib/mongestry.rb', line 137

def depth
  self.ancestry.split('/').size rescue 0
end

#descendant_idsObject

Returns a list of a descendant ids



122
123
124
# File 'lib/mongestry.rb', line 122

def descendant_ids
  self.descendants.map(&:id)
end

#descendantsObject

Scopes the model on direct and indirect children of the record



116
117
118
119
# 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?Boolean

Returns true if the record has any children, false otherwise

Returns:

  • (Boolean)


86
87
88
# File 'lib/mongestry.rb', line 86

def has_children?
  !self.children.to_a.blank?
end

#has_siblings?Boolean

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

Returns:

  • (Boolean)


106
107
108
# File 'lib/mongestry.rb', line 106

def has_siblings?
  self.siblings.present?
end

#is_childless?Boolean

Returns true if the record has no childen, false otherwise

Returns:

  • (Boolean)


91
92
93
# File 'lib/mongestry.rb', line 91

def is_childless?
  !self.has_children?
end

#is_only_child?Boolean

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

Returns:

  • (Boolean)


111
112
113
# File 'lib/mongestry.rb', line 111

def is_only_child?
  !self.has_siblings?
end

#is_root?Boolean

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

Returns:

  • (Boolean)


66
67
68
# File 'lib/mongestry.rb', line 66

def is_root?
  self.ancestry.nil?
end

#parentObject

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



45
46
47
# File 'lib/mongestry.rb', line 45

def parent
  self.class.where(_id: self.ancestry.split('/').last).first rescue nil
end

#parent_idObject

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



50
51
52
# File 'lib/mongestry.rb', line 50

def parent_id
  self.parent.id rescue nil
end

#rootObject

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



55
56
57
58
# File 'lib/mongestry.rb', line 55

def root
  return self unless self.ancestry
  self.class.where(_id: self.ancestry.split('/').first).first
end

#root_idObject

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



61
62
63
# File 'lib/mongestry.rb', line 61

def root_id
  self.root.id
end

#sibling_idsObject

Returns a list of sibling ids



101
102
103
# File 'lib/mongestry.rb', line 101

def sibling_ids
  self.siblings.map(&:id)
end

#siblingsObject

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



96
97
98
# File 'lib/mongestry.rb', line 96

def siblings
  self.class.where(:ancestry => self.ancestry.to_s).and(:_id => {'$ne' => self.id})
end

#subtreeObject

Scopes the model on descendants and itself



127
128
129
# File 'lib/mongestry.rb', line 127

def subtree
  self.class.where(_id: {"$in" => self.descendant_ids.push(self.id)})
end

#subtree_idsObject

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



132
133
134
# File 'lib/mongestry.rb', line 132

def subtree_ids
  self.subtree.map(&:id)
end