tree.rb
上传用户:netsea168
上传日期:2022-07-22
资源大小:4652k
文件大小:4k
源码类别:

Ajax

开发平台:

Others

  1. module ActiveRecord
  2.   module Acts
  3.     module Tree
  4.       def self.included(base)
  5.         base.extend(ClassMethods)
  6.       end
  7.       # Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children
  8.       # association. This requires that you have a foreign key column, which by default is called +parent_id+.
  9.       #
  10.       #   class Category < ActiveRecord::Base
  11.       #     acts_as_tree :order => "name"
  12.       #   end
  13.       #
  14.       #   Example:
  15.       #   root
  16.       #    _ child1
  17.       #         _ subchild1
  18.       #         _ subchild2
  19.       #
  20.       #   root      = Category.create("name" => "root")
  21.       #   child1    = root.children.create("name" => "child1")
  22.       #   subchild1 = child1.children.create("name" => "subchild1")
  23.       #
  24.       #   root.parent   # => nil
  25.       #   child1.parent # => root
  26.       #   root.children # => [child1]
  27.       #   root.children.first.children.first # => subchild1
  28.       #
  29.       # In addition to the parent and children associations, the following instance methods are added to the class
  30.       # after calling <tt>acts_as_tree</tt>:
  31.       # * <tt>siblings</tt> - Returns all the children of the parent, excluding the current node (<tt>[subchild2]</tt> when called on <tt>subchild1</tt>)
  32.       # * <tt>self_and_siblings</tt> - Returns all the children of the parent, including the current node (<tt>[subchild1, subchild2]</tt> when called on <tt>subchild1</tt>)
  33.       # * <tt>ancestors</tt> - Returns all the ancestors of the current node (<tt>[child1, root]</tt> when called on <tt>subchild2</tt>)
  34.       # * <tt>root</tt> - Returns the root of the current node (<tt>root</tt> when called on <tt>subchild2</tt>)
  35.       module ClassMethods
  36.         # Configuration options are:
  37.         #
  38.         # * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+)
  39.         # * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet.
  40.         # * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+).
  41.         def acts_as_tree(options = {})
  42.           configuration = { :foreign_key => "parent_id", :order => nil, :counter_cache => nil }
  43.           configuration.update(options) if options.is_a?(Hash)
  44.           belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
  45.           has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => :destroy
  46.           class_eval <<-EOV
  47.             include ActiveRecord::Acts::Tree::InstanceMethods
  48.             def self.roots
  49.               find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
  50.             end
  51.             def self.root
  52.               find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
  53.             end
  54.           EOV
  55.         end
  56.       end
  57.       module InstanceMethods
  58.         # Returns list of ancestors, starting from parent until root.
  59.         #
  60.         #   subchild1.ancestors # => [child1, root]
  61.         def ancestors
  62.           node, nodes = self, []
  63.           nodes << node = node.parent while node.parent
  64.           nodes
  65.         end
  66.         # Returns the root node of the tree.
  67.         def root
  68.           node = self
  69.           node = node.parent while node.parent
  70.           node
  71.         end
  72.         # Returns all siblings of the current node.
  73.         #
  74.         #   subchild1.siblings # => [subchild2]
  75.         def siblings
  76.           self_and_siblings - [self]
  77.         end
  78.         # Returns all siblings and a reference to the current node.
  79.         #
  80.         #   subchild1.self_and_siblings # => [subchild1, subchild2]
  81.         def self_and_siblings
  82.           parent ? parent.children : self.class.roots
  83.         end
  84.       end
  85.     end
  86.   end
  87. end