shuber-acts_as_tree 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +14 -0
 - data/MIT-LICENSE +20 -0
 - data/README.markdown +45 -0
 - data/Rakefile +22 -0
 - data/init.rb +1 -0
 - data/lib/acts_as_tree.rb +125 -0
 - data/test/acts_as_tree_test.rb +251 -0
 - metadata +61 -0
 
    
        data/CHANGELOG
    ADDED
    
    | 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            2009-01-15 - Sean Huber (shuber@huberry.com)
         
     | 
| 
      
 2 
     | 
    
         
            +
              * Remove unused test/fixture files
         
     | 
| 
      
 3 
     | 
    
         
            +
              * Remove nested active_record/acts/tree file structure
         
     | 
| 
      
 4 
     | 
    
         
            +
              * Update README
         
     | 
| 
      
 5 
     | 
    
         
            +
              * Add MIT-LICENSE
         
     | 
| 
      
 6 
     | 
    
         
            +
              * Update documentation
         
     | 
| 
      
 7 
     | 
    
         
            +
              * Clean up logic
         
     | 
| 
      
 8 
     | 
    
         
            +
              * Gemify
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            2008-08-18 - Sean Huber (shuber@huberry.com)
         
     | 
| 
      
 11 
     | 
    
         
            +
            	* Added is_root? instance method and tests
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            2008-08-18 - Sean Huber (shuber@huberry.com)
         
     | 
| 
      
 14 
     | 
    
         
            +
            	* The foreign_key for "parent" can't be a reference to the current node or any of its children
         
     | 
    
        data/MIT-LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2007 David Heinemeier Hansson
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 4 
     | 
    
         
            +
            a copy of this software and associated documentation files (the
         
     | 
| 
      
 5 
     | 
    
         
            +
            "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 6 
     | 
    
         
            +
            without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 7 
     | 
    
         
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 8 
     | 
    
         
            +
            permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 9 
     | 
    
         
            +
            the following conditions:
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be
         
     | 
| 
      
 12 
     | 
    
         
            +
            included in all copies or substantial portions of the Software.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 15 
     | 
    
         
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 16 
     | 
    
         
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 17 
     | 
    
         
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 18 
     | 
    
         
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 19 
     | 
    
         
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 20 
     | 
    
         
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README.markdown
    ADDED
    
    | 
         @@ -0,0 +1,45 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # acts\_as\_tree #
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Specify this `acts_as` extension if you want to model a tree structure by providing parent and children associations
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            ## Installation ##
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            	gem install shuber-acts_as_tree --source http://gems.github.com
         
     | 
| 
      
 9 
     | 
    
         
            +
            	OR
         
     | 
| 
      
 10 
     | 
    
         
            +
            	script/plugin install git://github.com/shuber/acts_as_tree.git
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ## Usage ##
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            Requires a `:foreign_key` option which defaults to `:parent_id`
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            	class Category < ActiveRecord::Base
         
     | 
| 
      
 18 
     | 
    
         
            +
            	  # schema
         
     | 
| 
      
 19 
     | 
    
         
            +
            	  #   id,        integer
         
     | 
| 
      
 20 
     | 
    
         
            +
            	  #   parent_id, integer
         
     | 
| 
      
 21 
     | 
    
         
            +
            	  #   name,      string
         
     | 
| 
      
 22 
     | 
    
         
            +
            	  
         
     | 
| 
      
 23 
     | 
    
         
            +
            	  acts_as_tree
         
     | 
| 
      
 24 
     | 
    
         
            +
            	end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            Also accepts `:order` and `:counter_cache` (defaults to `false`) options
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            ## Example ##
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            	root
         
     | 
| 
      
 32 
     | 
    
         
            +
            	  \_ child1
         
     | 
| 
      
 33 
     | 
    
         
            +
            	    \_ subchild1
         
     | 
| 
      
 34 
     | 
    
         
            +
            	    \_ subchild2
         
     | 
| 
      
 35 
     | 
    
         
            +
            	
         
     | 
| 
      
 36 
     | 
    
         
            +
            	root      = Category.create(:name => 'root')
         
     | 
| 
      
 37 
     | 
    
         
            +
            	child1    = root.children.create(:name => 'child1')
         
     | 
| 
      
 38 
     | 
    
         
            +
            	subchild1 = child1.children.create(:name => 'subchild1')
         
     | 
| 
      
 39 
     | 
    
         
            +
            	
         
     | 
| 
      
 40 
     | 
    
         
            +
            	root.parent   # nil
         
     | 
| 
      
 41 
     | 
    
         
            +
            	child1.parent # root
         
     | 
| 
      
 42 
     | 
    
         
            +
            	root.children # [child1]
         
     | 
| 
      
 43 
     | 
    
         
            +
            	root.children.first.children.first # subchild1
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rake'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rake/testtask'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rake/rdoctask'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            desc 'Default: run unit tests.'
         
     | 
| 
      
 6 
     | 
    
         
            +
            task :default => :test
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            desc 'Test acts_as_tree gem/plugin.'
         
     | 
| 
      
 9 
     | 
    
         
            +
            Rake::TestTask.new(:test) do |t|
         
     | 
| 
      
 10 
     | 
    
         
            +
              t.libs << 'lib'
         
     | 
| 
      
 11 
     | 
    
         
            +
              t.pattern = 'test/**/*_test.rb'
         
     | 
| 
      
 12 
     | 
    
         
            +
              t.verbose = true
         
     | 
| 
      
 13 
     | 
    
         
            +
            end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            desc 'Generate documentation for acts_as_tree gem/plugin.'
         
     | 
| 
      
 16 
     | 
    
         
            +
            Rake::RDocTask.new(:rdoc) do |rdoc|
         
     | 
| 
      
 17 
     | 
    
         
            +
              rdoc.rdoc_dir = 'rdoc'
         
     | 
| 
      
 18 
     | 
    
         
            +
              rdoc.title    = 'acts_as_tree'
         
     | 
| 
      
 19 
     | 
    
         
            +
              rdoc.options << '--line-numbers' << '--inline-source'
         
     | 
| 
      
 20 
     | 
    
         
            +
              rdoc.rdoc_files.include('README.markdown')
         
     | 
| 
      
 21 
     | 
    
         
            +
              rdoc.rdoc_files.include('lib/**/*.rb')
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
    
        data/init.rb
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'acts_as_tree'
         
     | 
    
        data/lib/acts_as_tree.rb
    ADDED
    
    | 
         @@ -0,0 +1,125 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module ActiveRecord
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Acts
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Tree
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def self.included(base)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    base.extend(ClassMethods)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
                  
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Returns all children (recursively) of the current node
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  #   parent.all_children # [child1, child1_child1, child1_child2, child2, child2_child1, child3]
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def all_children
         
     | 
| 
      
 12 
     | 
    
         
            +
                    self_and_all_children - [self]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                  
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # Returns list of ancestors, starting from parent until root
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   subchild1.ancestors # [child1, root]
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def ancestors
         
     | 
| 
      
 19 
     | 
    
         
            +
                    node, nodes = self, []
         
     | 
| 
      
 20 
     | 
    
         
            +
                    nodes << node = node.parent while node.parent
         
     | 
| 
      
 21 
     | 
    
         
            +
                    nodes
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # Checks if the current node is a root
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #
         
     | 
| 
      
 26 
     | 
    
         
            +
                  #   parent.is_root? # true
         
     | 
| 
      
 27 
     | 
    
         
            +
                  #   child.is_root? # false
         
     | 
| 
      
 28 
     | 
    
         
            +
                  def is_root?
         
     | 
| 
      
 29 
     | 
    
         
            +
                    !new_record? && parent.nil?
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # Returns the root node of the tree
         
     | 
| 
      
 33 
     | 
    
         
            +
                  def root
         
     | 
| 
      
 34 
     | 
    
         
            +
                    node = self
         
     | 
| 
      
 35 
     | 
    
         
            +
                    node = node.parent while node.parent
         
     | 
| 
      
 36 
     | 
    
         
            +
                    node
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
                  
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # Returns all siblings of the current node
         
     | 
| 
      
 40 
     | 
    
         
            +
                  #
         
     | 
| 
      
 41 
     | 
    
         
            +
                  #   subchild1.siblings # [subchild2]
         
     | 
| 
      
 42 
     | 
    
         
            +
                  def siblings
         
     | 
| 
      
 43 
     | 
    
         
            +
                    self_and_siblings - [self]
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                  
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # Returns all children (recursively) and a reference to the current node
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #
         
     | 
| 
      
 48 
     | 
    
         
            +
                  #   parent.self_and_all_children # [parent, child1, child1_child1, child1_child2, child2, child2_child1, child3]
         
     | 
| 
      
 49 
     | 
    
         
            +
                  def self_and_all_children
         
     | 
| 
      
 50 
     | 
    
         
            +
                    children.inject([self]) { |array, child| array += child.self_and_all_children }.flatten
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
                  
         
     | 
| 
      
 53 
     | 
    
         
            +
                  # Returns all siblings and a reference to the current node
         
     | 
| 
      
 54 
     | 
    
         
            +
                  #
         
     | 
| 
      
 55 
     | 
    
         
            +
                  #   subchild1.self_and_siblings # [subchild1, subchild2]
         
     | 
| 
      
 56 
     | 
    
         
            +
                  def self_and_siblings
         
     | 
| 
      
 57 
     | 
    
         
            +
                    parent ? parent.children : self.class.roots
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  
         
     | 
| 
      
 60 
     | 
    
         
            +
                  module ClassMethods
         
     | 
| 
      
 61 
     | 
    
         
            +
                    # Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children
         
     | 
| 
      
 62 
     | 
    
         
            +
                    # association. This requires that you have a foreign key column, which by default is called +parent_id+.
         
     | 
| 
      
 63 
     | 
    
         
            +
                    #
         
     | 
| 
      
 64 
     | 
    
         
            +
                    #   class Category < ActiveRecord::Base
         
     | 
| 
      
 65 
     | 
    
         
            +
                    #     acts_as_tree :order => :name
         
     | 
| 
      
 66 
     | 
    
         
            +
                    #   end
         
     | 
| 
      
 67 
     | 
    
         
            +
                    #
         
     | 
| 
      
 68 
     | 
    
         
            +
                    #   Example:
         
     | 
| 
      
 69 
     | 
    
         
            +
                    #   root
         
     | 
| 
      
 70 
     | 
    
         
            +
                    #    \_ child1
         
     | 
| 
      
 71 
     | 
    
         
            +
                    #         \_ subchild1
         
     | 
| 
      
 72 
     | 
    
         
            +
                    #         \_ subchild2
         
     | 
| 
      
 73 
     | 
    
         
            +
                    #
         
     | 
| 
      
 74 
     | 
    
         
            +
                    #   root      = Category.create(:name => 'root')
         
     | 
| 
      
 75 
     | 
    
         
            +
                    #   child1    = root.children.create(:name => 'child1')
         
     | 
| 
      
 76 
     | 
    
         
            +
                    #   subchild1 = child1.children.create(:name => 'subchild1')
         
     | 
| 
      
 77 
     | 
    
         
            +
                    #
         
     | 
| 
      
 78 
     | 
    
         
            +
                    #   root.parent   # nil
         
     | 
| 
      
 79 
     | 
    
         
            +
                    #   child1.parent # root
         
     | 
| 
      
 80 
     | 
    
         
            +
                    #   root.children # [child1]
         
     | 
| 
      
 81 
     | 
    
         
            +
                    #   root.children.first.children.first # subchild1
         
     | 
| 
      
 82 
     | 
    
         
            +
                    #
         
     | 
| 
      
 83 
     | 
    
         
            +
                    # In addition to the parent and children associations, the following instance methods are added to the class
         
     | 
| 
      
 84 
     | 
    
         
            +
                    # after calling <tt>acts_as_tree</tt>:
         
     | 
| 
      
 85 
     | 
    
         
            +
                    #   * <tt>siblings</tt> - Returns all the children of the parent, excluding the current node (<tt>[subchild2]</tt> when called on <tt>subchild1</tt>)
         
     | 
| 
      
 86 
     | 
    
         
            +
                    #   * <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>)
         
     | 
| 
      
 87 
     | 
    
         
            +
                    #   * <tt>ancestors</tt> - Returns all the ancestors of the current node (<tt>[child1, root]</tt> when called on <tt>subchild2</tt>)
         
     | 
| 
      
 88 
     | 
    
         
            +
                    #   * <tt>root</tt> - Returns the root of the current node (<tt>root</tt> when called on <tt>subchild2</tt>)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    #   * <tt>all_children</tt> - Returns all of the children of the parent recursively
         
     | 
| 
      
 90 
     | 
    
         
            +
                    #   * <tt>self_and_all_children</tt> - Returns the parent and all of its children recursively
         
     | 
| 
      
 91 
     | 
    
         
            +
                    #
         
     | 
| 
      
 92 
     | 
    
         
            +
                    # Configuration options are:
         
     | 
| 
      
 93 
     | 
    
         
            +
                    #
         
     | 
| 
      
 94 
     | 
    
         
            +
                    #   * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    #   * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet.
         
     | 
| 
      
 96 
     | 
    
         
            +
                    #   * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+).
         
     | 
| 
      
 97 
     | 
    
         
            +
                    def acts_as_tree(options = {})
         
     | 
| 
      
 98 
     | 
    
         
            +
                      options = { :class_name => name, :counter_cache => nil, :foreign_key => :parent_id, :order => nil }.merge(options)
         
     | 
| 
      
 99 
     | 
    
         
            +
                      options[:order] = "#{table_name}.#{options[:order]} ASC" if options[:order].is_a?(Symbol)
         
     | 
| 
      
 100 
     | 
    
         
            +
                      
         
     | 
| 
      
 101 
     | 
    
         
            +
                      belongs_to :parent, :class_name => options[:class_name], :foreign_key => options[:foreign_key], :counter_cache => options[:counter_cache]
         
     | 
| 
      
 102 
     | 
    
         
            +
                      has_many :children, :class_name => options[:class_name], :foreign_key => options[:foreign_key], :order => options[:order], :dependent => :destroy
         
     | 
| 
      
 103 
     | 
    
         
            +
                      
         
     | 
| 
      
 104 
     | 
    
         
            +
                      named_scope :roots, :conditions => "#{table_name}.#{options[:foreign_key]} IS NULL", :order => options[:order]
         
     | 
| 
      
 105 
     | 
    
         
            +
                      
         
     | 
| 
      
 106 
     | 
    
         
            +
                      validate_on_update :ensure_foreign_key_does_not_reference_self_or_all_children
         
     | 
| 
      
 107 
     | 
    
         
            +
                      
         
     | 
| 
      
 108 
     | 
    
         
            +
                      define_method 'ensure_foreign_key_does_not_reference_self_or_all_children' do
         
     | 
| 
      
 109 
     | 
    
         
            +
                        if self_and_all_children.detect { |node| node.id == send(options[:foreign_key]) }
         
     | 
| 
      
 110 
     | 
    
         
            +
                          self.errors.add(options[:foreign_key], "can't be a reference to the current node or any of its children")
         
     | 
| 
      
 111 
     | 
    
         
            +
                          false
         
     | 
| 
      
 112 
     | 
    
         
            +
                        end
         
     | 
| 
      
 113 
     | 
    
         
            +
                      end
         
     | 
| 
      
 114 
     | 
    
         
            +
                    end
         
     | 
| 
      
 115 
     | 
    
         
            +
                    
         
     | 
| 
      
 116 
     | 
    
         
            +
                    # Returns the first root node
         
     | 
| 
      
 117 
     | 
    
         
            +
                    def root
         
     | 
| 
      
 118 
     | 
    
         
            +
                      roots.find(:first)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    end
         
     | 
| 
      
 120 
     | 
    
         
            +
                  end
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
              end
         
     | 
| 
      
 123 
     | 
    
         
            +
            end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            ActiveRecord::Base.send :include, ActiveRecord::Acts::Tree
         
     | 
| 
         @@ -0,0 +1,251 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 3 
     | 
    
         
            +
            gem 'activerecord', '>= 2.1.0'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'active_record'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/../lib/acts_as_tree'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class Test::Unit::TestCase
         
     | 
| 
      
 8 
     | 
    
         
            +
              def assert_queries(num = 1)
         
     | 
| 
      
 9 
     | 
    
         
            +
                $query_count = 0
         
     | 
| 
      
 10 
     | 
    
         
            +
                yield
         
     | 
| 
      
 11 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 12 
     | 
    
         
            +
                assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed."
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def assert_no_queries(&block)
         
     | 
| 
      
 16 
     | 
    
         
            +
                assert_queries(0, &block)
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            # AR keeps printing annoying schema statements
         
     | 
| 
      
 23 
     | 
    
         
            +
            $stdout = StringIO.new
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            def setup_db
         
     | 
| 
      
 26 
     | 
    
         
            +
              ActiveRecord::Base.logger
         
     | 
| 
      
 27 
     | 
    
         
            +
              ActiveRecord::Schema.define(:version => 1) do
         
     | 
| 
      
 28 
     | 
    
         
            +
                create_table :mixins do |t|
         
     | 
| 
      
 29 
     | 
    
         
            +
                  t.column :type, :string
         
     | 
| 
      
 30 
     | 
    
         
            +
                  t.column :parent_id, :integer
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            def teardown_db
         
     | 
| 
      
 36 
     | 
    
         
            +
              ActiveRecord::Base.connection.tables.each do |table|
         
     | 
| 
      
 37 
     | 
    
         
            +
                ActiveRecord::Base.connection.drop_table(table)
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            class Mixin < ActiveRecord::Base
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            class TreeMixin < Mixin 
         
     | 
| 
      
 45 
     | 
    
         
            +
              acts_as_tree :foreign_key => "parent_id", :order => "id"
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            class TreeMixinWithoutOrder < Mixin
         
     | 
| 
      
 49 
     | 
    
         
            +
              acts_as_tree :foreign_key => "parent_id"
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            class RecursivelyCascadedTreeMixin < Mixin
         
     | 
| 
      
 53 
     | 
    
         
            +
              acts_as_tree :foreign_key => "parent_id"
         
     | 
| 
      
 54 
     | 
    
         
            +
              has_one :first_child, :class_name => 'RecursivelyCascadedTreeMixin', :foreign_key => :parent_id
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            class TreeTest < Test::Unit::TestCase
         
     | 
| 
      
 58 
     | 
    
         
            +
              
         
     | 
| 
      
 59 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 60 
     | 
    
         
            +
                setup_db
         
     | 
| 
      
 61 
     | 
    
         
            +
                @root1 = TreeMixin.create!
         
     | 
| 
      
 62 
     | 
    
         
            +
                @root_child1 = TreeMixin.create! :parent_id => @root1.id
         
     | 
| 
      
 63 
     | 
    
         
            +
                @child1_child = TreeMixin.create! :parent_id => @root_child1.id
         
     | 
| 
      
 64 
     | 
    
         
            +
                @root_child2 = TreeMixin.create! :parent_id => @root1.id
         
     | 
| 
      
 65 
     | 
    
         
            +
                @root2 = TreeMixin.create!
         
     | 
| 
      
 66 
     | 
    
         
            +
                @root3 = TreeMixin.create!
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
              def teardown
         
     | 
| 
      
 70 
     | 
    
         
            +
                teardown_db
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              def test_children
         
     | 
| 
      
 74 
     | 
    
         
            +
                assert_equal @root1.children, [@root_child1, @root_child2]
         
     | 
| 
      
 75 
     | 
    
         
            +
                assert_equal @root_child1.children, [@child1_child]
         
     | 
| 
      
 76 
     | 
    
         
            +
                assert_equal @child1_child.children, []
         
     | 
| 
      
 77 
     | 
    
         
            +
                assert_equal @root_child2.children, []
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
              def test_parent
         
     | 
| 
      
 81 
     | 
    
         
            +
                assert_equal @root_child1.parent, @root1
         
     | 
| 
      
 82 
     | 
    
         
            +
                assert_equal @root_child1.parent, @root_child2.parent
         
     | 
| 
      
 83 
     | 
    
         
            +
                assert_nil @root1.parent
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
              def test_delete
         
     | 
| 
      
 87 
     | 
    
         
            +
                assert_equal 6, TreeMixin.count
         
     | 
| 
      
 88 
     | 
    
         
            +
                @root1.destroy
         
     | 
| 
      
 89 
     | 
    
         
            +
                assert_equal 2, TreeMixin.count
         
     | 
| 
      
 90 
     | 
    
         
            +
                @root2.destroy
         
     | 
| 
      
 91 
     | 
    
         
            +
                @root3.destroy
         
     | 
| 
      
 92 
     | 
    
         
            +
                assert_equal 0, TreeMixin.count
         
     | 
| 
      
 93 
     | 
    
         
            +
              end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
              def test_insert
         
     | 
| 
      
 96 
     | 
    
         
            +
                @extra = @root1.children.create
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                assert @extra
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                assert_equal @extra.parent, @root1
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                assert_equal 3, @root1.children.size
         
     | 
| 
      
 103 
     | 
    
         
            +
                assert @root1.children.include?(@extra)
         
     | 
| 
      
 104 
     | 
    
         
            +
                assert @root1.children.include?(@root_child1)
         
     | 
| 
      
 105 
     | 
    
         
            +
                assert @root1.children.include?(@root_child2)
         
     | 
| 
      
 106 
     | 
    
         
            +
              end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
              def test_ancestors
         
     | 
| 
      
 109 
     | 
    
         
            +
                assert_equal [], @root1.ancestors
         
     | 
| 
      
 110 
     | 
    
         
            +
                assert_equal [@root1], @root_child1.ancestors
         
     | 
| 
      
 111 
     | 
    
         
            +
                assert_equal [@root_child1, @root1], @child1_child.ancestors
         
     | 
| 
      
 112 
     | 
    
         
            +
                assert_equal [@root1], @root_child2.ancestors
         
     | 
| 
      
 113 
     | 
    
         
            +
                assert_equal [], @root2.ancestors
         
     | 
| 
      
 114 
     | 
    
         
            +
                assert_equal [], @root3.ancestors
         
     | 
| 
      
 115 
     | 
    
         
            +
              end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
              def test_root
         
     | 
| 
      
 118 
     | 
    
         
            +
                assert_equal @root1, TreeMixin.root
         
     | 
| 
      
 119 
     | 
    
         
            +
                assert_equal @root1, @root1.root
         
     | 
| 
      
 120 
     | 
    
         
            +
                assert_equal @root1, @root_child1.root
         
     | 
| 
      
 121 
     | 
    
         
            +
                assert_equal @root1, @child1_child.root
         
     | 
| 
      
 122 
     | 
    
         
            +
                assert_equal @root1, @root_child2.root
         
     | 
| 
      
 123 
     | 
    
         
            +
                assert_equal @root2, @root2.root
         
     | 
| 
      
 124 
     | 
    
         
            +
                assert_equal @root3, @root3.root
         
     | 
| 
      
 125 
     | 
    
         
            +
              end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
              def test_roots
         
     | 
| 
      
 128 
     | 
    
         
            +
                assert_equal [@root1, @root2, @root3], TreeMixin.roots
         
     | 
| 
      
 129 
     | 
    
         
            +
              end
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
              def test_siblings
         
     | 
| 
      
 132 
     | 
    
         
            +
                assert_equal [@root2, @root3], @root1.siblings
         
     | 
| 
      
 133 
     | 
    
         
            +
                assert_equal [@root_child2], @root_child1.siblings
         
     | 
| 
      
 134 
     | 
    
         
            +
                assert_equal [], @child1_child.siblings
         
     | 
| 
      
 135 
     | 
    
         
            +
                assert_equal [@root_child1], @root_child2.siblings
         
     | 
| 
      
 136 
     | 
    
         
            +
                assert_equal [@root1, @root3], @root2.siblings
         
     | 
| 
      
 137 
     | 
    
         
            +
                assert_equal [@root1, @root2], @root3.siblings
         
     | 
| 
      
 138 
     | 
    
         
            +
              end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
              def test_self_and_siblings
         
     | 
| 
      
 141 
     | 
    
         
            +
                assert_equal [@root1, @root2, @root3], @root1.self_and_siblings
         
     | 
| 
      
 142 
     | 
    
         
            +
                assert_equal [@root_child1, @root_child2], @root_child1.self_and_siblings
         
     | 
| 
      
 143 
     | 
    
         
            +
                assert_equal [@child1_child], @child1_child.self_and_siblings
         
     | 
| 
      
 144 
     | 
    
         
            +
                assert_equal [@root_child1, @root_child2], @root_child2.self_and_siblings
         
     | 
| 
      
 145 
     | 
    
         
            +
                assert_equal [@root1, @root2, @root3], @root2.self_and_siblings
         
     | 
| 
      
 146 
     | 
    
         
            +
                assert_equal [@root1, @root2, @root3], @root3.self_and_siblings
         
     | 
| 
      
 147 
     | 
    
         
            +
              end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
            	def test_all_children
         
     | 
| 
      
 150 
     | 
    
         
            +
            		assert_equal [@root_child1, @child1_child, @root_child2], @root1.all_children
         
     | 
| 
      
 151 
     | 
    
         
            +
            		assert_equal [@child1_child], @root_child1.all_children
         
     | 
| 
      
 152 
     | 
    
         
            +
            		assert_equal [], @child1_child.all_children
         
     | 
| 
      
 153 
     | 
    
         
            +
            	end
         
     | 
| 
      
 154 
     | 
    
         
            +
            	
         
     | 
| 
      
 155 
     | 
    
         
            +
            	def test_self_and_all_children
         
     | 
| 
      
 156 
     | 
    
         
            +
            		assert_equal [@root1, @root_child1, @child1_child, @root_child2], @root1.self_and_all_children
         
     | 
| 
      
 157 
     | 
    
         
            +
            		assert_equal [@child1_child], @child1_child.self_and_all_children
         
     | 
| 
      
 158 
     | 
    
         
            +
            	end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
            	def test_should_not_reference_self_as_parent_id_on_update
         
     | 
| 
      
 161 
     | 
    
         
            +
            		@root1.parent_id = @root1.id
         
     | 
| 
      
 162 
     | 
    
         
            +
            		assert !@root1.save
         
     | 
| 
      
 163 
     | 
    
         
            +
            		assert @root1.errors.on(:parent_id)
         
     | 
| 
      
 164 
     | 
    
         
            +
            	end
         
     | 
| 
      
 165 
     | 
    
         
            +
            	
         
     | 
| 
      
 166 
     | 
    
         
            +
            	def test_should_not_reference_children_as_parent_id_on_update
         
     | 
| 
      
 167 
     | 
    
         
            +
            		@root1.parent_id = @root_child1.id
         
     | 
| 
      
 168 
     | 
    
         
            +
            		assert !@root1.save
         
     | 
| 
      
 169 
     | 
    
         
            +
            		assert @root1.errors.on(:parent_id)
         
     | 
| 
      
 170 
     | 
    
         
            +
            		
         
     | 
| 
      
 171 
     | 
    
         
            +
            		@root1.reload
         
     | 
| 
      
 172 
     | 
    
         
            +
            		@root1.parent_id = @child1_child.id
         
     | 
| 
      
 173 
     | 
    
         
            +
            		assert !@root1.save
         
     | 
| 
      
 174 
     | 
    
         
            +
            		assert @root1.errors.on(:parent_id)
         
     | 
| 
      
 175 
     | 
    
         
            +
            	end
         
     | 
| 
      
 176 
     | 
    
         
            +
            	
         
     | 
| 
      
 177 
     | 
    
         
            +
            	def test_is_root
         
     | 
| 
      
 178 
     | 
    
         
            +
            	  assert @root1.is_root?
         
     | 
| 
      
 179 
     | 
    
         
            +
            	  assert !@root_child1.is_root?
         
     | 
| 
      
 180 
     | 
    
         
            +
            	  assert !TreeMixin.new.is_root?
         
     | 
| 
      
 181 
     | 
    
         
            +
              end
         
     | 
| 
      
 182 
     | 
    
         
            +
            end
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
            class TreeTestWithEagerLoading < Test::Unit::TestCase
         
     | 
| 
      
 185 
     | 
    
         
            +
              
         
     | 
| 
      
 186 
     | 
    
         
            +
              def setup 
         
     | 
| 
      
 187 
     | 
    
         
            +
                teardown_db
         
     | 
| 
      
 188 
     | 
    
         
            +
                setup_db
         
     | 
| 
      
 189 
     | 
    
         
            +
                @root1 = TreeMixin.create!
         
     | 
| 
      
 190 
     | 
    
         
            +
                @root_child1 = TreeMixin.create! :parent_id => @root1.id
         
     | 
| 
      
 191 
     | 
    
         
            +
                @child1_child = TreeMixin.create! :parent_id => @root_child1.id
         
     | 
| 
      
 192 
     | 
    
         
            +
                @root_child2 = TreeMixin.create! :parent_id => @root1.id
         
     | 
| 
      
 193 
     | 
    
         
            +
                @root2 = TreeMixin.create!
         
     | 
| 
      
 194 
     | 
    
         
            +
                @root3 = TreeMixin.create!
         
     | 
| 
      
 195 
     | 
    
         
            +
                
         
     | 
| 
      
 196 
     | 
    
         
            +
                @rc1 = RecursivelyCascadedTreeMixin.create!
         
     | 
| 
      
 197 
     | 
    
         
            +
                @rc2 = RecursivelyCascadedTreeMixin.create! :parent_id => @rc1.id 
         
     | 
| 
      
 198 
     | 
    
         
            +
                @rc3 = RecursivelyCascadedTreeMixin.create! :parent_id => @rc2.id
         
     | 
| 
      
 199 
     | 
    
         
            +
                @rc4 = RecursivelyCascadedTreeMixin.create! :parent_id => @rc3.id
         
     | 
| 
      
 200 
     | 
    
         
            +
              end
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
              def teardown
         
     | 
| 
      
 203 
     | 
    
         
            +
                teardown_db
         
     | 
| 
      
 204 
     | 
    
         
            +
              end
         
     | 
| 
      
 205 
     | 
    
         
            +
                
         
     | 
| 
      
 206 
     | 
    
         
            +
              def test_eager_association_loading
         
     | 
| 
      
 207 
     | 
    
         
            +
                roots = TreeMixin.find(:all, :include => :children, :conditions => "mixins.parent_id IS NULL", :order => "mixins.id")
         
     | 
| 
      
 208 
     | 
    
         
            +
                assert_equal [@root1, @root2, @root3], roots                     
         
     | 
| 
      
 209 
     | 
    
         
            +
                assert_no_queries do
         
     | 
| 
      
 210 
     | 
    
         
            +
                  assert_equal 2, roots[0].children.size
         
     | 
| 
      
 211 
     | 
    
         
            +
                  assert_equal 0, roots[1].children.size
         
     | 
| 
      
 212 
     | 
    
         
            +
                  assert_equal 0, roots[2].children.size
         
     | 
| 
      
 213 
     | 
    
         
            +
                end   
         
     | 
| 
      
 214 
     | 
    
         
            +
              end
         
     | 
| 
      
 215 
     | 
    
         
            +
              
         
     | 
| 
      
 216 
     | 
    
         
            +
              def test_eager_association_loading_with_recursive_cascading_three_levels_has_many
         
     | 
| 
      
 217 
     | 
    
         
            +
                root_node = RecursivelyCascadedTreeMixin.find(:first, :include => { :children => { :children => :children } }, :order => 'mixins.id')
         
     | 
| 
      
 218 
     | 
    
         
            +
                assert_equal @rc4, assert_no_queries { root_node.children.first.children.first.children.first }
         
     | 
| 
      
 219 
     | 
    
         
            +
              end
         
     | 
| 
      
 220 
     | 
    
         
            +
              
         
     | 
| 
      
 221 
     | 
    
         
            +
              def test_eager_association_loading_with_recursive_cascading_three_levels_has_one
         
     | 
| 
      
 222 
     | 
    
         
            +
                root_node = RecursivelyCascadedTreeMixin.find(:first, :include => { :first_child => { :first_child => :first_child } }, :order => 'mixins.id')
         
     | 
| 
      
 223 
     | 
    
         
            +
                assert_equal @rc4, assert_no_queries { root_node.first_child.first_child.first_child }
         
     | 
| 
      
 224 
     | 
    
         
            +
              end
         
     | 
| 
      
 225 
     | 
    
         
            +
              
         
     | 
| 
      
 226 
     | 
    
         
            +
              def test_eager_association_loading_with_recursive_cascading_three_levels_belongs_to
         
     | 
| 
      
 227 
     | 
    
         
            +
                leaf_node = RecursivelyCascadedTreeMixin.find(:first, :include => { :parent => { :parent => :parent } }, :order => 'mixins.id DESC')
         
     | 
| 
      
 228 
     | 
    
         
            +
                assert_equal @rc1, assert_no_queries { leaf_node.parent.parent.parent }
         
     | 
| 
      
 229 
     | 
    
         
            +
              end 
         
     | 
| 
      
 230 
     | 
    
         
            +
            end
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
            class TreeTestWithoutOrder < Test::Unit::TestCase
         
     | 
| 
      
 233 
     | 
    
         
            +
              
         
     | 
| 
      
 234 
     | 
    
         
            +
              def setup                               
         
     | 
| 
      
 235 
     | 
    
         
            +
                setup_db
         
     | 
| 
      
 236 
     | 
    
         
            +
                @root1 = TreeMixinWithoutOrder.create!
         
     | 
| 
      
 237 
     | 
    
         
            +
                @root2 = TreeMixinWithoutOrder.create!
         
     | 
| 
      
 238 
     | 
    
         
            +
              end
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
              def teardown
         
     | 
| 
      
 241 
     | 
    
         
            +
                teardown_db
         
     | 
| 
      
 242 
     | 
    
         
            +
              end
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
              def test_root
         
     | 
| 
      
 245 
     | 
    
         
            +
                assert [@root1, @root2].include?(TreeMixinWithoutOrder.root)
         
     | 
| 
      
 246 
     | 
    
         
            +
              end
         
     | 
| 
      
 247 
     | 
    
         
            +
              
         
     | 
| 
      
 248 
     | 
    
         
            +
              def test_roots
         
     | 
| 
      
 249 
     | 
    
         
            +
                assert_equal [], [@root1, @root2] - TreeMixinWithoutOrder.roots
         
     | 
| 
      
 250 
     | 
    
         
            +
              end
         
     | 
| 
      
 251 
     | 
    
         
            +
            end 
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,61 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: shuber-acts_as_tree
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.0.0
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Sean Huber
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2009-01-15 00:00:00 -08:00
         
     | 
| 
      
 13 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 14 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            description: Allows you to create tree structures with ActiveRecord
         
     | 
| 
      
 17 
     | 
    
         
            +
            email: shuber@huberry.com
         
     | 
| 
      
 18 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 25 
     | 
    
         
            +
            - CHANGELOG
         
     | 
| 
      
 26 
     | 
    
         
            +
            - init.rb
         
     | 
| 
      
 27 
     | 
    
         
            +
            - lib/acts_as_tree.rb
         
     | 
| 
      
 28 
     | 
    
         
            +
            - MIT-LICENSE
         
     | 
| 
      
 29 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 30 
     | 
    
         
            +
            - README.markdown
         
     | 
| 
      
 31 
     | 
    
         
            +
            has_rdoc: false
         
     | 
| 
      
 32 
     | 
    
         
            +
            homepage: http://github.com/shuber/acts_as_tree
         
     | 
| 
      
 33 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 34 
     | 
    
         
            +
            rdoc_options: 
         
     | 
| 
      
 35 
     | 
    
         
            +
            - --line-numbers
         
     | 
| 
      
 36 
     | 
    
         
            +
            - --inline-source
         
     | 
| 
      
 37 
     | 
    
         
            +
            - --main
         
     | 
| 
      
 38 
     | 
    
         
            +
            - README.markdown
         
     | 
| 
      
 39 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 40 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 41 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 42 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 43 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 44 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 45 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 46 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 47 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 48 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 49 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 50 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 51 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 52 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 53 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 56 
     | 
    
         
            +
            rubygems_version: 1.2.0
         
     | 
| 
      
 57 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 58 
     | 
    
         
            +
            specification_version: 2
         
     | 
| 
      
 59 
     | 
    
         
            +
            summary: Allows you to create tree structures with ActiveRecord
         
     | 
| 
      
 60 
     | 
    
         
            +
            test_files: 
         
     | 
| 
      
 61 
     | 
    
         
            +
            - test/acts_as_tree_test.rb
         
     |