annotate .svn/pristine/c3/c33e5d7a26ef296362a6e8027933b0a079928cbd.svn-base @ 1524:82fac3dcf466 redmine-2.5-integration

Fix failure to interpret Javascript when autocompleting members for project
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Thu, 11 Sep 2014 10:24:38 +0100
parents dffacf8a6908
children
rev   line source
Chris@1517 1 module ActiveRecord
Chris@1517 2 module Acts
Chris@1517 3 module Tree
Chris@1517 4 def self.included(base)
Chris@1517 5 base.extend(ClassMethods)
Chris@1517 6 end
Chris@1517 7
Chris@1517 8 # Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children
Chris@1517 9 # association. This requires that you have a foreign key column, which by default is called +parent_id+.
Chris@1517 10 #
Chris@1517 11 # class Category < ActiveRecord::Base
Chris@1517 12 # acts_as_tree :order => "name"
Chris@1517 13 # end
Chris@1517 14 #
Chris@1517 15 # Example:
Chris@1517 16 # root
Chris@1517 17 # \_ child1
Chris@1517 18 # \_ subchild1
Chris@1517 19 # \_ subchild2
Chris@1517 20 #
Chris@1517 21 # root = Category.create("name" => "root")
Chris@1517 22 # child1 = root.children.create("name" => "child1")
Chris@1517 23 # subchild1 = child1.children.create("name" => "subchild1")
Chris@1517 24 #
Chris@1517 25 # root.parent # => nil
Chris@1517 26 # child1.parent # => root
Chris@1517 27 # root.children # => [child1]
Chris@1517 28 # root.children.first.children.first # => subchild1
Chris@1517 29 #
Chris@1517 30 # In addition to the parent and children associations, the following instance methods are added to the class
Chris@1517 31 # after calling <tt>acts_as_tree</tt>:
Chris@1517 32 # * <tt>siblings</tt> - Returns all the children of the parent, excluding the current node (<tt>[subchild2]</tt> when called on <tt>subchild1</tt>)
Chris@1517 33 # * <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>)
Chris@1517 34 # * <tt>ancestors</tt> - Returns all the ancestors of the current node (<tt>[child1, root]</tt> when called on <tt>subchild2</tt>)
Chris@1517 35 # * <tt>root</tt> - Returns the root of the current node (<tt>root</tt> when called on <tt>subchild2</tt>)
Chris@1517 36 module ClassMethods
Chris@1517 37 # Configuration options are:
Chris@1517 38 #
Chris@1517 39 # * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+)
Chris@1517 40 # * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet.
Chris@1517 41 # * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+).
Chris@1517 42 def acts_as_tree(options = {})
Chris@1517 43 configuration = { :foreign_key => "parent_id", :dependent => :destroy, :order => nil, :counter_cache => nil }
Chris@1517 44 configuration.update(options) if options.is_a?(Hash)
Chris@1517 45
Chris@1517 46 belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
Chris@1517 47 has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => configuration[:dependent]
Chris@1517 48
Chris@1517 49 scope :roots, lambda {
Chris@1517 50 where("#{configuration[:foreign_key]} IS NULL").
Chris@1517 51 order(configuration[:order])
Chris@1517 52 }
Chris@1517 53 send :include, ActiveRecord::Acts::Tree::InstanceMethods
Chris@1517 54 end
Chris@1517 55 end
Chris@1517 56
Chris@1517 57 module InstanceMethods
Chris@1517 58 # Returns list of ancestors, starting from parent until root.
Chris@1517 59 #
Chris@1517 60 # subchild1.ancestors # => [child1, root]
Chris@1517 61 def ancestors
Chris@1517 62 node, nodes = self, []
Chris@1517 63 nodes << node = node.parent while node.parent
Chris@1517 64 nodes
Chris@1517 65 end
Chris@1517 66
Chris@1517 67 # Returns list of descendants.
Chris@1517 68 #
Chris@1517 69 # root.descendants # => [child1, subchild1, subchild2]
Chris@1517 70 def descendants(depth=nil)
Chris@1517 71 depth ||= 0
Chris@1517 72 result = children.dup
Chris@1517 73 unless depth == 1
Chris@1517 74 result += children.collect {|child| child.descendants(depth-1)}.flatten
Chris@1517 75 end
Chris@1517 76 result
Chris@1517 77 end
Chris@1517 78
Chris@1517 79 # Returns list of descendants and a reference to the current node.
Chris@1517 80 #
Chris@1517 81 # root.self_and_descendants # => [root, child1, subchild1, subchild2]
Chris@1517 82 def self_and_descendants(depth=nil)
Chris@1517 83 [self] + descendants(depth)
Chris@1517 84 end
Chris@1517 85
Chris@1517 86 # Returns the root node of the tree.
Chris@1517 87 def root
Chris@1517 88 node = self
Chris@1517 89 node = node.parent while node.parent
Chris@1517 90 node
Chris@1517 91 end
Chris@1517 92
Chris@1517 93 # Returns all siblings of the current node.
Chris@1517 94 #
Chris@1517 95 # subchild1.siblings # => [subchild2]
Chris@1517 96 def siblings
Chris@1517 97 self_and_siblings - [self]
Chris@1517 98 end
Chris@1517 99
Chris@1517 100 # Returns all siblings and a reference to the current node.
Chris@1517 101 #
Chris@1517 102 # subchild1.self_and_siblings # => [subchild1, subchild2]
Chris@1517 103 def self_and_siblings
Chris@1517 104 parent ? parent.children : self.class.roots
Chris@1517 105 end
Chris@1517 106 end
Chris@1517 107 end
Chris@1517 108 end
Chris@1517 109 end