Module: Mongoid::Acts::NestedSet::Document::ClassMethods

Includes:
Fields, Rebuild, Validation
Defined in:
lib/mongoid_nested_set/document.rb

Instance Method Summary collapse

Methods included from Fields

#left_field_name, #outline_number_field_name, #parent_field_name, #quoted_left_field_name, #quoted_parent_field_name, #quoted_right_field_name, #quoted_scope_field_names, #right_field_name, #scope_class, #scope_field_names

Methods included from Validation

#all_roots_valid?, #each_root_valid?, #left_and_rights_valid?, #no_duplicates_for_fields?, #valid?

Methods included from Rebuild

#rebuild!

Instance Method Details

#after_move(*args, &block) ⇒ Object



121
122
123
# File 'lib/mongoid_nested_set/document.rb', line 121

def after_move(*args, &block)
  set_callback :move, :after, *args, &block
end

#before_move(*args, &block) ⇒ Object



116
117
118
# File 'lib/mongoid_nested_set/document.rb', line 116

def before_move(*args, &block)
  set_callback :move, :before, *args, &block
end

#descendants_of(parents) ⇒ Object

Provides a chainable relation to select all descendants of a set of records, excluding the record set itself. Similar to parent.descendants, except this allows you to find all descendants of a set of nodes, rather than being restricted to find the descendants of only a single node.

Example:

parents = Category.roots.all
parents_descendants = Category.where(:deleted => false).descendants_of(parents)


103
104
105
106
107
108
109
110
111
112
113
# File 'lib/mongoid_nested_set/document.rb', line 103

def descendants_of(parents)
  # TODO: Add root or scope?
  conditions = parents.map do |parent|
    {left_field_name => {"$gt" => parent.left}, right_field_name => {"$lt" => parent.right}}
  end
  if conditions.empty?
    where({})
  else
    where("$or" => conditions)
  end
end

#each_with_ancestors(objects) ⇒ Object

Iterates over tree elements with ancestors. Only accepts default ordering, ordering by an other field than lft does not work. This is much more efficient than calling ancestors for each object because it doesn’t require any additional database queries.

Example:

Category.each_with_ancestors(Category.root.self_and_descendants) do |o, ancestors|


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/mongoid_nested_set/document.rb', line 70

def each_with_ancestors(objects)
  ancestors = nil
  last_parent = nil
  objects.each do |o|
    if ancestors == nil
      ancestors = o.root? ? [] : o.ancestors.entries
    end
    if ancestors.empty? || o.parent_id != ancestors.last.id
      # we are on a new level, did we descend or ascend?
      if ancestors.any? {|a| a.id == o.parent_id}
        # ascend
        ancestors.pop while (!ancestors.empty? && ancestors.last.id != o.parent_id)
      elsif !o.root?
        # descend
        ancestors << last_parent
      end
    end
    yield(o, ancestors)
    last_parent = o
  end
end

#each_with_level(objects) ⇒ Object

Iterates over tree elements and determines the current level in the tree. Only accepts default ordering, ordering by an other field than lft does not work. This method is much more efficient then calling level because it doesn’t require any additional database queries. This method does not used the cached depth field.

Example:

Category.each_with_level(Category.root.self_and_descendants) do |o, level|


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/mongoid_nested_set/document.rb', line 41

def each_with_level(objects)
  offset = nil
  path = [nil]
  objects.each do |o|
    if offset == nil
      offset = o.parent_id.nil? ? 0 : o.parent.level
    end
    if o.parent_id != path.last
      # we are on a new level, did we descend or ascend?
      if path.include?(o.parent_id)
        # remove wrong tailing path elements
        path.pop while path.last != o.parent_id
      else
        path << o.parent_id
      end
    end
    yield(o, path.length - 1 + offset)
  end
end

#rootObject

Returns the first root



18
19
20
# File 'lib/mongoid_nested_set/document.rb', line 18

def root
  roots.first
end

#scope_condition_by_options(options) ⇒ Object



23
24
25
26
27
28
29
# File 'lib/mongoid_nested_set/document.rb', line 23

def scope_condition_by_options(options)
  h = {}
  scope_string = Array(acts_as_nested_set_options[:scope]).reject{|s| !options.has_key?(s) }.each do |c|
    h[c] = options[c]
  end
  h
end