coupa-acts_as_tree 1.0.20090229
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/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
|
+
|