module CollectiveIdea::Acts::NestedSet::Model::Relatable

Public Instance Methods

ancestors() click to toggle source

Returns an collection of all parents

# File lib/awesome_nested_set/model/relatable.rb, line 8
def ancestors
  without_self self_and_ancestors
end
descendants() click to toggle source

Returns a collection including all of its children and nested children

# File lib/awesome_nested_set/model/relatable.rb, line 43
def descendants
  without_self self_and_descendants
end
is_ancestor_of?(other) click to toggle source
# File lib/awesome_nested_set/model/relatable.rb, line 61
def is_ancestor_of?(other)
  within_node?(self, other) && same_scope?(other)
end
is_descendant_of?(other) click to toggle source
# File lib/awesome_nested_set/model/relatable.rb, line 53
def is_descendant_of?(other)
  within_node?(other, self) && same_scope?(other)
end
is_or_is_ancestor_of?(other) click to toggle source
# File lib/awesome_nested_set/model/relatable.rb, line 65
def is_or_is_ancestor_of?(other)
  (self == other || within_node?(self, other)) && same_scope?(other)
end
is_or_is_descendant_of?(other) click to toggle source
# File lib/awesome_nested_set/model/relatable.rb, line 57
def is_or_is_descendant_of?(other)
  (other == self || within_node?(other, self)) && same_scope?(other)
end
leaves() click to toggle source

Returns a set of all of its nested children which do not have children

# File lib/awesome_nested_set/model/relatable.rb, line 30
def leaves
  descendants.where(
    "#{quoted_right_column_full_name} - #{quoted_left_column_full_name} = 1"
  )
end
left_sibling() click to toggle source

Find the first sibling to the left

# File lib/awesome_nested_set/model/relatable.rb, line 77
def left_sibling
  siblings.left_of(left).last
end
level() click to toggle source

Returns the level of this object in the tree root level is 0

# File lib/awesome_nested_set/model/relatable.rb, line 38
def level
  parent_id.nil? ? 0 : compute_level
end
right_sibling() click to toggle source

Find the first sibling to the right

# File lib/awesome_nested_set/model/relatable.rb, line 82
def right_sibling
  siblings.right_of(left).first
end
root() click to toggle source
# File lib/awesome_nested_set/model/relatable.rb, line 86
def root
  return self_and_ancestors.children_of(nil).first if persisted?

  if parent_id && current_parent = nested_set_scope.where(primary_column_name => parent_id).first!
    current_parent.root
  else
    self
  end
end
same_scope?(other) click to toggle source

Check if other model is in the same scope

# File lib/awesome_nested_set/model/relatable.rb, line 70
def same_scope?(other)
  Array(acts_as_nested_set_options[:scope]).all? do |attr|
    self.send(attr) == other.send(attr)
  end
end
self_and_ancestors() click to toggle source

Returns the collection of all parents and self

# File lib/awesome_nested_set/model/relatable.rb, line 13
def self_and_ancestors
  nested_set_scope.
    where(arel_table[left_column_name].lteq(left)).
    where(arel_table[right_column_name].gteq(right))
end
self_and_descendants() click to toggle source

Returns a collection including itself and all of its nested children

# File lib/awesome_nested_set/model/relatable.rb, line 48
def self_and_descendants
  # using _left_ for both sides here lets us benefit from an index on that column if one exists
  nested_set_scope.right_of(left).left_of(right)
end
self_and_siblings() click to toggle source

Returns the collection of all children of the parent, including self

# File lib/awesome_nested_set/model/relatable.rb, line 25
def self_and_siblings
  nested_set_scope.children_of parent_id
end
siblings() click to toggle source

Returns the collection of all children of the parent, except self

# File lib/awesome_nested_set/model/relatable.rb, line 20
def siblings
  without_self self_and_siblings
end

Protected Instance Methods

compute_level() click to toggle source
# File lib/awesome_nested_set/model/relatable.rb, line 98
def compute_level
  node, nesting = determine_depth

  node == self ? ancestors.count : node.level + nesting
end
determine_depth(node = self, nesting = 0) click to toggle source
# File lib/awesome_nested_set/model/relatable.rb, line 104
def determine_depth(node = self, nesting = 0)
  while (association = node.association(:parent)).loaded? && association.target
    nesting += 1
    node = node.parent
  end if node.respond_to?(:association)

  [node, nesting]
end
within_node?(node, within) click to toggle source
# File lib/awesome_nested_set/model/relatable.rb, line 113
def within_node?(node, within)
  node.left < within.left && within.left < node.right
end