From 8f5d331e9ba55848585fd50359267255c4ffa185 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 11 Sep 2007 05:46:43 +0000 Subject: [PATCH] Fix generic file name in main load path. --- Rakefile | 4 +- init.rb | 2 +- lib/active_record/acts/tree.rb | 96 ++++++++++++++++++++++++++++++++++ lib/acts_as_tree.rb | 94 --------------------------------- test/abstract_unit.rb | 5 +- 5 files changed, 102 insertions(+), 99 deletions(-) create mode 100644 lib/active_record/acts/tree.rb delete mode 100644 lib/acts_as_tree.rb diff --git a/Rakefile b/Rakefile index 1ded626..da091d9 100644 --- a/Rakefile +++ b/Rakefile @@ -12,10 +12,10 @@ Rake::TestTask.new(:test) do |t| t.verbose = true end -desc 'Generate documentation for in_place_editing plugin.' +desc 'Generate documentation for acts_as_tree plugin.' Rake::RDocTask.new(:rdoc) do |rdoc| rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'InPlaceEditing' + rdoc.title = 'acts_as_tree' rdoc.options << '--line-numbers' << '--inline-source' rdoc.rdoc_files.include('README') rdoc.rdoc_files.include('lib/**/*.rb') diff --git a/init.rb b/init.rb index 87eae28..0901ddb 100644 --- a/init.rb +++ b/init.rb @@ -1 +1 @@ -require 'acts_as_tree' \ No newline at end of file +ActiveRecord::Base.send :include, ActiveRecord::Acts::Tree diff --git a/lib/active_record/acts/tree.rb b/lib/active_record/acts/tree.rb new file mode 100644 index 0000000..d59dbf0 --- /dev/null +++ b/lib/active_record/acts/tree.rb @@ -0,0 +1,96 @@ +module ActiveRecord + module Acts + module Tree + def self.included(base) + base.extend(ClassMethods) + end + + # Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children + # association. This requires that you have a foreign key column, which by default is called +parent_id+. + # + # class Category < ActiveRecord::Base + # acts_as_tree :order => "name" + # end + # + # Example: + # root + # \_ child1 + # \_ subchild1 + # \_ subchild2 + # + # root = Category.create("name" => "root") + # child1 = root.children.create("name" => "child1") + # subchild1 = child1.children.create("name" => "subchild1") + # + # root.parent # => nil + # child1.parent # => root + # root.children # => [child1] + # root.children.first.children.first # => subchild1 + # + # In addition to the parent and children associations, the following instance methods are added to the class + # after calling acts_as_tree: + # * siblings - Returns all the children of the parent, excluding the current node ([subchild2] when called on subchild1) + # * self_and_siblings - Returns all the children of the parent, including the current node ([subchild1, subchild2] when called on subchild1) + # * ancestors - Returns all the ancestors of the current node ([child1, root] when called on subchild2) + # * root - Returns the root of the current node (root when called on subchild2) + module ClassMethods + # Configuration options are: + # + # * foreign_key - specifies the column name to use for tracking of the tree (default: +parent_id+) + # * order - makes it possible to sort the children according to this SQL snippet. + # * counter_cache - keeps a count in a +children_count+ column if set to +true+ (default: +false+). + def acts_as_tree(options = {}) + configuration = { :foreign_key => "parent_id", :order => nil, :counter_cache => nil } + configuration.update(options) if options.is_a?(Hash) + + belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache] + has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => :destroy + + class_eval <<-EOV + include ActsAsTree::InstanceMethods + + def self.roots + find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}) + end + + def self.root + find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}) + end + EOV + end + end + + module InstanceMethods + # Returns list of ancestors, starting from parent until root. + # + # subchild1.ancestors # => [child1, root] + def ancestors + node, nodes = self, [] + nodes << node = node.parent while node.parent + nodes + end + + # Returns the root node of the tree. + def root + node = self + node = node.parent while node.parent + node + end + + # Returns all siblings of the current node. + # + # subchild1.siblings # => [subchild2] + def siblings + self_and_siblings - [self] + end + + # Returns all siblings and a reference to the current node. + # + # subchild1.self_and_siblings # => [subchild1, subchild2] + def self_and_siblings + parent ? parent.children : self.class.roots + end + end + end + end +end diff --git a/lib/acts_as_tree.rb b/lib/acts_as_tree.rb deleted file mode 100644 index 43802e5..0000000 --- a/lib/acts_as_tree.rb +++ /dev/null @@ -1,94 +0,0 @@ -module ActsAsTree - def self.included(base) - base.extend(ClassMethods) - end - - # Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children - # association. This requires that you have a foreign key column, which by default is called +parent_id+. - # - # class Category < ActiveRecord::Base - # acts_as_tree :order => "name" - # end - # - # Example: - # root - # \_ child1 - # \_ subchild1 - # \_ subchild2 - # - # root = Category.create("name" => "root") - # child1 = root.children.create("name" => "child1") - # subchild1 = child1.children.create("name" => "subchild1") - # - # root.parent # => nil - # child1.parent # => root - # root.children # => [child1] - # root.children.first.children.first # => subchild1 - # - # In addition to the parent and children associations, the following instance methods are added to the class - # after calling acts_as_tree: - # * siblings - Returns all the children of the parent, excluding the current node ([subchild2] when called on subchild1) - # * self_and_siblings - Returns all the children of the parent, including the current node ([subchild1, subchild2] when called on subchild1) - # * ancestors - Returns all the ancestors of the current node ([child1, root] when called on subchild2) - # * root - Returns the root of the current node (root when called on subchild2) - module ClassMethods - # Configuration options are: - # - # * foreign_key - specifies the column name to use for tracking of the tree (default: +parent_id+) - # * order - makes it possible to sort the children according to this SQL snippet. - # * counter_cache - keeps a count in a +children_count+ column if set to +true+ (default: +false+). - def acts_as_tree(options = {}) - configuration = { :foreign_key => "parent_id", :order => nil, :counter_cache => nil } - configuration.update(options) if options.is_a?(Hash) - - belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache] - has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => :destroy - - class_eval <<-EOV - include ActsAsTree::InstanceMethods - - def self.roots - find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}) - end - - def self.root - find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}) - end - EOV - end - end - - module InstanceMethods - # Returns list of ancestors, starting from parent until root. - # - # subchild1.ancestors # => [child1, root] - def ancestors - node, nodes = self, [] - nodes << node = node.parent while node.parent - nodes - end - - # Returns the root node of the tree. - def root - node = self - node = node.parent while node.parent - node - end - - # Returns all siblings of the current node. - # - # subchild1.siblings # => [subchild2] - def siblings - self_and_siblings - [self] - end - - # Returns all siblings and a reference to the current node. - # - # subchild1.self_and_siblings # => [subchild1, subchild2] - def self_and_siblings - parent ? parent.children : self.class.roots - end - end -end - -ActiveRecord::Base.send(:include, ActsAsTree) diff --git a/test/abstract_unit.rb b/test/abstract_unit.rb index 0c00404..ceb405b 100644 --- a/test/abstract_unit.rb +++ b/test/abstract_unit.rb @@ -1,12 +1,13 @@ $:.unshift(File.dirname(__FILE__) + '/../../../rails/activesupport/lib') $:.unshift(File.dirname(__FILE__) + '/../../../rails/activerecord/lib') -$:.unshift(File.dirname(__FILE__) + '/../lib') require 'test/unit' require 'active_support' require 'active_record' require 'active_record/fixtures' -require 'acts_as_tree' + +$:.unshift(File.dirname(__FILE__) + '/../lib') +require "#{File.dirname(__FILE__)}/../init" config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml')) ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")