Module: TinySupport::ActiveRecord::NestedSet::Model
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/tiny_support/active_record/nested_set.rb
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#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
Returns true if this is the end of a branch.
-
#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_child_with_index(node, index) ⇒ Object
Move the node to the child of another node with specify index (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_ordered_child_of(parent, order_attribute, ascending = true) ⇒ Object
Order children in a nested set by an attribute Can order by any attribute class that uses the Comparable mixin, for example a string or integer Usage example when sorting categories alphabetically: @new_category.move_to_ordered_child_of(@root, “name”).
-
#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.
- #name_with_level ⇒ Object
- #nested_set_options(options = {}, &block) ⇒ Object
-
#parent_id ⇒ Object
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.
-
#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
Instance Method Details
#ancestors ⇒ Object
Returns an array of all parents
396 397 398 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 396 def ancestors without_self self_and_ancestors end |
#child? ⇒ Boolean
Returns true is this is a child node
371 372 373 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 371 def child? !root? end |
#descendants ⇒ Object
Returns a set of all of its children and nested children
430 431 432 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 430 def descendants without_self self_and_descendants end |
#is_ancestor_of?(other) ⇒ Boolean
442 443 444 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 442 def is_ancestor_of?(other) self.left < other.left && other.left < self.right && same_scope?(other) end |
#is_descendant_of?(other) ⇒ Boolean
434 435 436 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 434 def is_descendant_of?(other) other.left < self.left && self.left < other.right && same_scope?(other) end |
#is_or_is_ancestor_of?(other) ⇒ Boolean
446 447 448 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 446 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
438 439 440 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 438 def is_or_is_descendant_of?(other) other.left <= self.left && self.left < other.right && same_scope?(other) end |
#leaf? ⇒ Boolean
Returns true if this is the end of a branch.
366 367 368 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 366 def leaf? persisted? && right.to_i - left.to_i == 1 end |
#leaves ⇒ Object
Returns a set of all of its nested children which do not have children
411 412 413 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 411 def leaves descendants.where("#{quoted_right_column_full_name} - #{quoted_left_column_full_name} = 1") end |
#left ⇒ Object
Value of the left column
351 352 353 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 351 def left self[left_column_name] end |
#left_sibling ⇒ Object
Find the first sibling to the left
458 459 460 461 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 458 def left_sibling siblings.where(["#{quoted_left_column_full_name} < ?", left]). order("#{quoted_left_column_full_name} DESC").last end |
#level ⇒ Object
Returns the level of this object in the tree root level is 0
417 418 419 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 417 def level parent_id.nil? ? 0 : compute_level end |
#move_left ⇒ Object
Shorthand method for finding the left sibling and moving to the left of it.
469 470 471 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 469 def move_left move_to_left_of left_sibling end |
#move_possible?(target) ⇒ Boolean
531 532 533 534 535 536 537 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 531 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.
474 475 476 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 474 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)
489 490 491 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 489 def move_to_child_of(node) move_to node, :child end |
#move_to_child_with_index(node, index) ⇒ Object
Move the node to the child of another node with specify index (you can pass id only)
494 495 496 497 498 499 500 501 502 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 494 def move_to_child_with_index(node, index) if node.children.empty? move_to_child_of(node) elsif node.children.count == index move_to_right_of(node.children.last) else move_to_left_of(node.children[index]) end end |
#move_to_left_of(node) ⇒ Object
Move the node to the left of another node (you can pass id only)
479 480 481 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 479 def move_to_left_of(node) move_to node, :left end |
#move_to_ordered_child_of(parent, order_attribute, ascending = true) ⇒ Object
Order children in a nested set by an attribute Can order by any attribute class that uses the Comparable mixin, for example a string or integer Usage example when sorting categories alphabetically: @new_category.move_to_ordered_child_of(@root, “name”)
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 512 def move_to_ordered_child_of(parent, order_attribute, ascending = true) self.move_to_root and return unless parent left = nil # This is needed, at least for the tests. parent.children.each do |n| # Find the node immediately to the left of this node. if ascending left = n if n.send(order_attribute) < self.send(order_attribute) else left = n if n.send(order_attribute) > self.send(order_attribute) end end self.move_to_child_of(parent) return unless parent.children.count > 1 # Only need to order if there are multiple children. if left # Self has a left neighbor. self.move_to_right_of(left) else # Self is the left most node. self.move_to_left_of(parent.children[0]) end end |
#move_to_right_of(node) ⇒ Object
Move the node to the left of another node (you can pass id only)
484 485 486 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 484 def move_to_right_of(node) move_to node, :right end |
#move_to_root ⇒ Object
Move the node to root nodes
505 506 507 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 505 def move_to_root move_to nil, :root end |
#name_with_level ⇒ Object
333 334 335 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 333 def name_with_level "#{'- ' * self.level}#{self.name}" end |
#nested_set_options(options = {}, &block) ⇒ Object
337 338 339 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 337 def ={}, &block self.class.({:items => self}.merge(), &block) end |
#parent_id ⇒ Object
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%'")
Value of the parent column
346 347 348 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 346 def parent_id self[parent_column_name] end |
#right ⇒ Object
Value of the right column
356 357 358 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 356 def right self[right_column_name] end |
#right_sibling ⇒ Object
Find the first sibling to the right
464 465 466 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 464 def right_sibling siblings.where(["#{quoted_left_column_full_name} > ?", left]).first end |
#root ⇒ Object
Returns root
376 377 378 379 380 381 382 383 384 385 386 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 376 def root if persisted? self_and_ancestors.where(parent_column_name => nil).first else if parent_id && current_parent = nested_set_scope.find(parent_id) current_parent.root else self end end end |
#root? ⇒ Boolean
Returns true if this is a root node.
361 362 363 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 361 def root? parent_id.nil? end |
#same_scope?(other) ⇒ Boolean
Check if other model is in the same scope
451 452 453 454 455 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 451 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
389 390 391 392 393 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 389 def self_and_ancestors nested_set_scope.where([ "#{quoted_left_column_full_name} <= ? AND #{quoted_right_column_full_name} >= ?", left, right ]) end |
#self_and_descendants ⇒ Object
Returns a set of itself and all of its nested children
422 423 424 425 426 427 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 422 def self_and_descendants nested_set_scope.where([ "#{quoted_left_column_full_name} >= ? AND #{quoted_left_column_full_name} < ?", left, right # using _left_ for both sides here lets us benefit from an index on that column if one exists ]) end |
#self_and_siblings ⇒ Object
Returns the array of all children of the parent, including self
401 402 403 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 401 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
406 407 408 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 406 def siblings without_self self_and_siblings end |
#to_text ⇒ Object
539 540 541 542 543 |
# File 'lib/tiny_support/active_record/nested_set.rb', line 539 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 |