coupa-acts_as_tree 1.0.20090229
Sign up to get free protection for your applications and to get access to all the features.
- data/README +26 -0
- data/Rakefile +22 -0
- data/acts_as_tree.gemspec +30 -0
- data/lib/active_record/acts/tree.rb +96 -0
- data/lib/coupa-acts_as_tree.rb +2 -0
- metadata +67 -0
data/README
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
acts_as_tree
|
2
|
+
============
|
3
|
+
|
4
|
+
Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children
|
5
|
+
association. This requires that you have a foreign key column, which by default is called +parent_id+.
|
6
|
+
|
7
|
+
class Category < ActiveRecord::Base
|
8
|
+
acts_as_tree :order => "name"
|
9
|
+
end
|
10
|
+
|
11
|
+
Example:
|
12
|
+
root
|
13
|
+
\_ child1
|
14
|
+
\_ subchild1
|
15
|
+
\_ subchild2
|
16
|
+
|
17
|
+
root = Category.create("name" => "root")
|
18
|
+
child1 = root.children.create("name" => "child1")
|
19
|
+
subchild1 = child1.children.create("name" => "subchild1")
|
20
|
+
|
21
|
+
root.parent # => nil
|
22
|
+
child1.parent # => root
|
23
|
+
root.children # => [child1]
|
24
|
+
root.children.first.children.first # => subchild1
|
25
|
+
|
26
|
+
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 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 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')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'acts_as_tree'
|
3
|
+
s.version = '1.0.20090229'
|
4
|
+
s.date = '2009-02-27'
|
5
|
+
|
6
|
+
s.summary = "Overrides some basic methods for the current model so that calling " +
|
7
|
+
"#destroy sets a 'deleted_at' field to the current timestamp. ActiveRecord is required."
|
8
|
+
s.description = "see README"
|
9
|
+
|
10
|
+
s.authors = ['David Heinemeier Hansson']
|
11
|
+
s.email = 'jerry@coupa.com'
|
12
|
+
s.homepage = 'http://github.com/coupa/acts_as_tree'
|
13
|
+
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.rdoc_options = ["--main", "README"]
|
16
|
+
s.extra_rdoc_files = ["README"]
|
17
|
+
|
18
|
+
s.add_dependency 'rails', ['>= 2.1']
|
19
|
+
|
20
|
+
s.files = [
|
21
|
+
"README",
|
22
|
+
"Rakefile",
|
23
|
+
"acts_as_tree.gemspec",
|
24
|
+
"lib/coupa-acts_as_tree.rb",
|
25
|
+
"lib/active_record/acts/tree.rb",
|
26
|
+
]
|
27
|
+
|
28
|
+
s.test_files = []
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Acts
|
3
|
+
module Tree
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
# Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children
|
9
|
+
# association. This requires that you have a foreign key column, which by default is called +parent_id+.
|
10
|
+
#
|
11
|
+
# class Category < ActiveRecord::Base
|
12
|
+
# acts_as_tree :order => "name"
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
# root
|
17
|
+
# \_ child1
|
18
|
+
# \_ subchild1
|
19
|
+
# \_ subchild2
|
20
|
+
#
|
21
|
+
# root = Category.create("name" => "root")
|
22
|
+
# child1 = root.children.create("name" => "child1")
|
23
|
+
# subchild1 = child1.children.create("name" => "subchild1")
|
24
|
+
#
|
25
|
+
# root.parent # => nil
|
26
|
+
# child1.parent # => root
|
27
|
+
# root.children # => [child1]
|
28
|
+
# root.children.first.children.first # => subchild1
|
29
|
+
#
|
30
|
+
# In addition to the parent and children associations, the following instance methods are added to the class
|
31
|
+
# after calling <tt>acts_as_tree</tt>:
|
32
|
+
# * <tt>siblings</tt> - Returns all the children of the parent, excluding the current node (<tt>[subchild2]</tt> when called on <tt>subchild1</tt>)
|
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>)
|
34
|
+
# * <tt>ancestors</tt> - Returns all the ancestors of the current node (<tt>[child1, root]</tt> when called on <tt>subchild2</tt>)
|
35
|
+
# * <tt>root</tt> - Returns the root of the current node (<tt>root</tt> when called on <tt>subchild2</tt>)
|
36
|
+
module ClassMethods
|
37
|
+
# Configuration options are:
|
38
|
+
#
|
39
|
+
# * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+)
|
40
|
+
# * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet.
|
41
|
+
# * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+).
|
42
|
+
def acts_as_tree(options = {})
|
43
|
+
configuration = { :foreign_key => "parent_id", :order => nil, :counter_cache => nil }
|
44
|
+
configuration.update(options) if options.is_a?(Hash)
|
45
|
+
|
46
|
+
belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
|
47
|
+
has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => :destroy
|
48
|
+
|
49
|
+
class_eval <<-EOV
|
50
|
+
include ActiveRecord::Acts::Tree::InstanceMethods
|
51
|
+
|
52
|
+
def self.roots
|
53
|
+
find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.root
|
57
|
+
find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
|
58
|
+
end
|
59
|
+
EOV
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module InstanceMethods
|
64
|
+
# Returns list of ancestors, starting from parent until root.
|
65
|
+
#
|
66
|
+
# subchild1.ancestors # => [child1, root]
|
67
|
+
def ancestors
|
68
|
+
node, nodes = self, []
|
69
|
+
nodes << node = node.parent while node.parent
|
70
|
+
nodes
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns the root node of the tree.
|
74
|
+
def root
|
75
|
+
node = self
|
76
|
+
node = node.parent while node.parent
|
77
|
+
node
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns all siblings of the current node.
|
81
|
+
#
|
82
|
+
# subchild1.siblings # => [subchild2]
|
83
|
+
def siblings
|
84
|
+
self_and_siblings - [self]
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns all siblings and a reference to the current node.
|
88
|
+
#
|
89
|
+
# subchild1.self_and_siblings # => [subchild1, subchild2]
|
90
|
+
def self_and_siblings
|
91
|
+
parent ? parent.children : self.class.roots
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: coupa-acts_as_tree
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.20090229
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Heinemeier Hansson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-02-27 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "2.1"
|
24
|
+
version:
|
25
|
+
description: see README
|
26
|
+
email: jerry@coupa.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README
|
33
|
+
files:
|
34
|
+
- README
|
35
|
+
- Rakefile
|
36
|
+
- acts_as_tree.gemspec
|
37
|
+
- lib/coupa-acts_as_tree.rb
|
38
|
+
- lib/active_record/acts/tree.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/coupa/acts_as_tree
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --main
|
44
|
+
- README
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.2.0
|
63
|
+
signing_key:
|
64
|
+
specification_version: 2
|
65
|
+
summary: "Overrides some basic methods for the current model so that calling #destroy sets a 'deleted_at' field to the current timestamp. ActiveRecord is required."
|
66
|
+
test_files: []
|
67
|
+
|