Module: CollectiveIdea::Acts::NestedSet::InstanceMethods
- Defined in:
- lib/awesome_nested_set.rb
Overview
Any instance method that returns a collection makes use of Rails 2.1’s named_scope (which is bundled for Rails 2.0), so it can be treated as a finder.
category.self_and_descendants.count
category.ancestors.find(:all, :conditions => "name like '%foo%'")
Instance Method Summary collapse
-
#<=>(x) ⇒ Object
order by left column.
-
#==(comparison_object) ⇒ Object
Redefine to act like active record.
-
#ancestors ⇒ Object
Returns an array of all parents.
-
#child? ⇒ Boolean
Returns true is this is a child node.
-
#descendants ⇒ Object
Returns a set of all of its children and nested children.
- #is_ancestor_of?(other) ⇒ Boolean
- #is_descendant_of?(other) ⇒ Boolean
- #is_or_is_ancestor_of?(other) ⇒ Boolean
- #is_or_is_descendant_of?(other) ⇒ Boolean
- #leaf? ⇒ Boolean
-
#leaves ⇒ Object
Returns a set of all of its nested children which do not have children.
-
#left ⇒ Object
Value of the left column.
-
#left_sibling ⇒ Object
Find the first sibling to the left.
-
#level ⇒ Object
Returns the level of this object in the tree root level is 0.
-
#move_left ⇒ Object
Shorthand method for finding the left sibling and moving to the left of it.
- #move_possible?(target) ⇒ Boolean
-
#move_right ⇒ Object
Shorthand method for finding the right sibling and moving to the right of it.
-
#move_to_child_of(node) ⇒ Object
Move the node to the child of another node (you can pass id only).
-
#move_to_left_of(node) ⇒ Object
Move the node to the left of another node (you can pass id only).
-
#move_to_right_of(node) ⇒ Object
Move the node to the left of another node (you can pass id only).
-
#move_to_root ⇒ Object
Move the node to root nodes.
-
#parent_id ⇒ Object
Value of the parent column.
-
#right ⇒ Object
Value of the right column.
-
#right_sibling ⇒ Object
Find the first sibling to the right.
-
#root ⇒ Object
Returns root.
-
#root? ⇒ Boolean
Returns true if this is a root node.
-
#same_scope?(other) ⇒ Boolean
Check if other model is in the same scope.
-
#self_and_ancestors ⇒ Object
Returns the array of all parents and self.
-
#self_and_descendants ⇒ Object
Returns a set of itself and all of its nested children.
-
#self_and_siblings ⇒ Object
Returns the array of all children of the parent, including self.
-
#siblings ⇒ Object
Returns the array of all children of the parent, except self.
- #to_text ⇒ Object
-
#traverse(flat = false, mover = nil, descendants = nil, level = self.level, &block) ⇒ Object
Returns self and its descendants as a nested array.
Instance Method Details
#<=>(x) ⇒ Object
order by left column
305 306 307 |
# File 'lib/awesome_nested_set.rb', line 305 def <=>(x) left <=> x.left end |
#==(comparison_object) ⇒ Object
Redefine to act like active record
310 311 312 313 314 315 |
# File 'lib/awesome_nested_set.rb', line 310 def ==(comparison_object) comparison_object.equal?(self) || (comparison_object.instance_of?(self.class) && comparison_object.id == id && !comparison_object.new_record?) end |
#ancestors ⇒ Object
Returns an array of all parents
328 329 330 |
# File 'lib/awesome_nested_set.rb', line 328 def ancestors without_self self_and_ancestors end |
#child? ⇒ Boolean
Returns true is this is a child node
300 301 302 |
# File 'lib/awesome_nested_set.rb', line 300 def child? !parent_id.nil? end |
#descendants ⇒ Object
Returns a set of all of its children and nested children
359 360 361 |
# File 'lib/awesome_nested_set.rb', line 359 def descendants without_self self_and_descendants end |
#is_ancestor_of?(other) ⇒ Boolean
371 372 373 |
# File 'lib/awesome_nested_set.rb', line 371 def is_ancestor_of?(other) self.left < other.left && other.left < self.right && same_scope?(other) end |
#is_descendant_of?(other) ⇒ Boolean
363 364 365 |
# File 'lib/awesome_nested_set.rb', line 363 def is_descendant_of?(other) other.left < self.left && self.left < other.right && same_scope?(other) end |
#is_or_is_ancestor_of?(other) ⇒ Boolean
375 376 377 |
# File 'lib/awesome_nested_set.rb', line 375 def is_or_is_ancestor_of?(other) self.left <= other.left && other.left < self.right && same_scope?(other) end |
#is_or_is_descendant_of?(other) ⇒ Boolean
367 368 369 |
# File 'lib/awesome_nested_set.rb', line 367 def is_or_is_descendant_of?(other) other.left <= self.left && self.left < other.right && same_scope?(other) end |
#leaf? ⇒ Boolean
295 296 297 |
# File 'lib/awesome_nested_set.rb', line 295 def leaf? !new_record? && right - left == 1 end |
#leaves ⇒ Object
Returns a set of all of its nested children which do not have children
343 344 345 |
# File 'lib/awesome_nested_set.rb', line 343 def leaves descendants.where("#{self.class.quoted_table_name}.#{quoted_right_column_name} - #{self.class.quoted_table_name}.#{quoted_left_column_name} = 1") end |
#left ⇒ Object
Value of the left column
281 282 283 |
# File 'lib/awesome_nested_set.rb', line 281 def left self[left_column_name] end |
#left_sibling ⇒ Object
Find the first sibling to the left
387 388 389 390 |
# File 'lib/awesome_nested_set.rb', line 387 def left_sibling siblings.find(:first, :conditions => ["#{self.class.quoted_table_name}.#{quoted_left_column_name} < ?", left], :order => "#{self.class.quoted_table_name}.#{quoted_left_column_name} DESC") end |
#level ⇒ Object
Returns the level of this object in the tree root level is 0
349 350 351 |
# File 'lib/awesome_nested_set.rb', line 349 def level parent_id.nil? ? 0 : ancestors.count end |
#move_left ⇒ Object
Shorthand method for finding the left sibling and moving to the left of it.
398 399 400 |
# File 'lib/awesome_nested_set.rb', line 398 def move_left move_to_left_of left_sibling end |
#move_possible?(target) ⇒ Boolean
427 428 429 430 431 432 433 |
# File 'lib/awesome_nested_set.rb', line 427 def move_possible?(target) self != target && # Can't target self same_scope?(target) && # can't be in different scopes # !(left..right).include?(target.left..target.right) # this needs tested more # detect impossible move !((left <= target.left && right >= target.left) or (left <= target.right && right >= target.right)) end |
#move_right ⇒ Object
Shorthand method for finding the right sibling and moving to the right of it.
403 404 405 |
# File 'lib/awesome_nested_set.rb', line 403 def move_right move_to_right_of right_sibling end |
#move_to_child_of(node) ⇒ Object
Move the node to the child of another node (you can pass id only)
418 419 420 |
# File 'lib/awesome_nested_set.rb', line 418 def move_to_child_of(node) move_to node, :child end |
#move_to_left_of(node) ⇒ Object
Move the node to the left of another node (you can pass id only)
408 409 410 |
# File 'lib/awesome_nested_set.rb', line 408 def move_to_left_of(node) move_to node, :left end |
#move_to_right_of(node) ⇒ Object
Move the node to the left of another node (you can pass id only)
413 414 415 |
# File 'lib/awesome_nested_set.rb', line 413 def move_to_right_of(node) move_to node, :right end |
#move_to_root ⇒ Object
Move the node to root nodes
423 424 425 |
# File 'lib/awesome_nested_set.rb', line 423 def move_to_root move_to nil, :root end |
#parent_id ⇒ Object
Value of the parent column
276 277 278 |
# File 'lib/awesome_nested_set.rb', line 276 def parent_id self[parent_column_name] end |
#right ⇒ Object
Value of the right column
286 287 288 |
# File 'lib/awesome_nested_set.rb', line 286 def right self[right_column_name] end |
#right_sibling ⇒ Object
Find the first sibling to the right
393 394 395 |
# File 'lib/awesome_nested_set.rb', line 393 def right_sibling siblings.find(:first, :conditions => ["#{self.class.quoted_table_name}.#{quoted_left_column_name} > ?", left]) end |
#root ⇒ Object
Returns root
318 319 320 |
# File 'lib/awesome_nested_set.rb', line 318 def root self_and_ancestors.first end |
#root? ⇒ Boolean
Returns true if this is a root node.
291 292 293 |
# File 'lib/awesome_nested_set.rb', line 291 def root? parent_id.nil? end |
#same_scope?(other) ⇒ Boolean
Check if other model is in the same scope
380 381 382 383 384 |
# File 'lib/awesome_nested_set.rb', line 380 def same_scope?(other) Array([:scope]).all? do |attr| self.send(attr) == other.send(attr) end end |
#self_and_ancestors ⇒ Object
Returns the array of all parents and self
323 324 325 |
# File 'lib/awesome_nested_set.rb', line 323 def self_and_ancestors nested_set_scope.where(["#{self.class.quoted_table_name}.#{quoted_left_column_name} <= ? AND #{self.class.quoted_table_name}.#{quoted_right_column_name} >= ?", left, right]) end |
#self_and_descendants ⇒ Object
Returns a set of itself and all of its nested children
354 355 356 |
# File 'lib/awesome_nested_set.rb', line 354 def self_and_descendants nested_set_scope.where(["#{self.class.quoted_table_name}.#{quoted_left_column_name} >= ? AND #{self.class.quoted_table_name}.#{quoted_right_column_name} <= ?", left, right]) end |
#self_and_siblings ⇒ Object
Returns the array of all children of the parent, including self
333 334 335 |
# File 'lib/awesome_nested_set.rb', line 333 def self_and_siblings nested_set_scope.where({parent_column_name => parent_id}) end |
#siblings ⇒ Object
Returns the array of all children of the parent, except self
338 339 340 |
# File 'lib/awesome_nested_set.rb', line 338 def siblings without_self self_and_siblings end |
#to_text ⇒ Object
435 436 437 438 439 |
# File 'lib/awesome_nested_set.rb', line 435 def to_text self_and_descendants.map do |node| "#{'*'*(node.level+1)} #{node.id} #{node.to_s} (#{node.parent_id}, #{node.left}, #{node.right})" end.join("\n") end |
#traverse(flat = false, mover = nil, descendants = nil, level = self.level, &block) ⇒ Object
Returns self and its descendants as a nested array. If flat is true then a flat array is returned instead. Specify mover to exclude any impossible moves. Pass a block to perform an operation on each item. The block arguments are |item, descendants, level|. The remaining arguments for this method are for recursion and should not normally be given.
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 |
# File 'lib/awesome_nested_set.rb', line 447 def traverse(flat = false, mover = nil, descendants = nil, level = self.level, &block) descendants ||= self.descendants array = [] while not descendants.empty? break unless descendants.first.parent_id == self.id item = descendants.shift items = item.traverse(flat, mover, descendants, level + 1, &block) array.send flat ? 'concat' : '<<', items if mover.nil? or mover.new_record? or mover.move_possible?(item) end item = block_given? ? yield(self, array, level) : self array.unshift item unless mover == self return array end |