acts_as_sane_tree 2.0.5 → 2.0.6
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.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +3 -0
- data/README.rdoc +10 -3
- data/lib/acts_as_sane_tree/acts_as_sane_tree.rb +19 -11
- data/lib/acts_as_sane_tree/instance_methods.rb +18 -17
- data/lib/acts_as_sane_tree/singleton_methods.rb +16 -16
- data/lib/acts_as_sane_tree/version.rb +1 -2
- metadata +36 -57
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 89a019d5241aef791604209335af604e3b6c926d
|
4
|
+
data.tar.gz: ab0d2f4d92b65230a7eaad525389bc102caa18a7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9ddd081548cbe842f2bca5562794753e7e6328ebe4c076c1d2fbb5d3ac8cc40a224a79f35bf9367b91bf8eb60ae4671083ea71d70358c2d305fd6bfcff12aae6
|
7
|
+
data.tar.gz: 72f023ab7fe05705c0dd2bc80d6c5fb4ae52005254aae72667a25048132161b4e75e70041cf62c5400f7f9b38318ace8ae9526ebf9c1822bcdf489d21b932a04
|
data/CHANGELOG.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
== acts_as_sane_tree
|
1
|
+
== acts_as_sane_tree
|
2
2
|
==== (Building trees with a dash of sanity)
|
3
3
|
|
4
|
+
{<img src="https://secure.travis-ci.org/chrisroberts/acts_as_sane_tree.png" />}[http://travis-ci.org/chrisroberts/acts_as_sane_tree]
|
5
|
+
|
4
6
|
This is a drop in replacement for acts_as_tree on systems with Postgresql >= 8.4
|
5
7
|
|
6
8
|
== What this provides
|
@@ -9,7 +11,12 @@ A fast way to build trees.
|
|
9
11
|
|
10
12
|
== What version of Rails
|
11
13
|
|
12
|
-
|
14
|
+
* Rails ~> 4.1.0
|
15
|
+
* Rails ~> 4.0.0
|
16
|
+
* Rails ~> 3.2.0
|
17
|
+
* Rails ~> 3.1.0
|
18
|
+
* Rails ~> 3.0.0
|
19
|
+
* Rails ~> 2.3.0
|
13
20
|
|
14
21
|
== Requirements
|
15
22
|
|
@@ -50,7 +57,7 @@ http://chrisroberts.github.com/acts_as_sane_tree
|
|
50
57
|
== License
|
51
58
|
|
52
59
|
A (now not so large) majority of this was copied directly from the original acts as tree, with the original license:
|
53
|
-
* Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license
|
60
|
+
* Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license
|
54
61
|
|
55
62
|
The new additions continue:
|
56
63
|
* Copyright (c) 2011 Chris Roberts, released under the MIT license
|
@@ -3,7 +3,7 @@ require 'acts_as_sane_tree/instance_methods'
|
|
3
3
|
require 'acts_as_sane_tree/singleton_methods.rb'
|
4
4
|
|
5
5
|
module ActsAsSaneTree
|
6
|
-
|
6
|
+
|
7
7
|
def self.included(base) # :nodoc:
|
8
8
|
base.extend(ClassMethods)
|
9
9
|
end
|
@@ -31,7 +31,7 @@ module ActsAsSaneTree
|
|
31
31
|
# root.children.first.children.first # => subchild1
|
32
32
|
#
|
33
33
|
# The following class methods are also added:
|
34
|
-
#
|
34
|
+
#
|
35
35
|
# * <tt>nodes_within?(src, chk)</tt> - Returns true if chk contains any nodes found within src and all ancestors of nodes within src
|
36
36
|
# * <tt>nodes_within(src, chk)</tt> - Returns any matching nodes from chk found within src and all ancestors within src
|
37
37
|
# * <tt>nodes_and_descendants(*args)</tt> - Returns all nodes and descendants for given IDs or records. Accepts multiple IDs and records. Valid options:
|
@@ -52,21 +52,29 @@ module ActsAsSaneTree
|
|
52
52
|
|
53
53
|
self.class_eval do
|
54
54
|
cattr_accessor :configuration
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
|
56
|
+
if(Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('4.1.0'))
|
57
|
+
has_many :children,
|
58
|
+
:class_name => @configuration[:class].name,
|
59
|
+
:foreign_key => @configuration[:foreign_key],
|
60
|
+
:order => @configuration[:order],
|
61
|
+
:dependent => @configuration[:dependent]
|
62
|
+
else
|
63
|
+
has_many :children,
|
64
|
+
proc{ order self.configuration[:order] },
|
65
|
+
:class_name => @configuration[:class].name,
|
66
|
+
:foreign_key => @configuration[:foreign_key],
|
67
|
+
:dependent => @configuration[:dependent]
|
68
|
+
end
|
69
|
+
belongs_to :parent,
|
70
|
+
:class_name => @configuration[:class].name,
|
63
71
|
:foreign_key => @configuration[:foreign_key]
|
64
72
|
if(@configuration[:parent_override])
|
65
73
|
def parent
|
66
74
|
self.class.where(:id => self.parent_id).first
|
67
75
|
end
|
68
76
|
end
|
69
|
-
|
77
|
+
|
70
78
|
validates_each @configuration[:foreign_key] do |record, attr, value|
|
71
79
|
record.errors.add attr, 'cannot be own parent.' if !record.id.nil? && value.to_i == record.id.to_i
|
72
80
|
end
|
@@ -1,28 +1,29 @@
|
|
1
1
|
module ActsAsSaneTree
|
2
2
|
module InstanceMethods
|
3
3
|
|
4
|
-
# Returns all ancestors of the current node.
|
4
|
+
# Returns all ancestors of the current node.
|
5
5
|
def ancestors
|
6
|
-
query =
|
6
|
+
query =
|
7
7
|
"(WITH RECURSIVE crumbs AS (
|
8
8
|
SELECT #{self.class.configuration[:class].table_name}.*,
|
9
9
|
1 AS depth
|
10
10
|
FROM #{self.class.configuration[:class].table_name}
|
11
|
-
WHERE id = #{id}
|
11
|
+
WHERE id = #{id}
|
12
12
|
UNION ALL
|
13
|
-
SELECT alias1.*,
|
14
|
-
depth + 1
|
13
|
+
SELECT alias1.*,
|
14
|
+
depth + 1
|
15
15
|
FROM crumbs
|
16
16
|
JOIN #{self.class.configuration[:class].table_name} alias1 ON alias1.id = crumbs.parent_id
|
17
17
|
) SELECT * FROM crumbs WHERE crumbs.id != #{id}) as #{self.class.configuration[:class].table_name}"
|
18
|
-
|
19
|
-
|
18
|
+
scope_strip_method = self.class.configuration[:class].methods.map(&:to_sym).include?(:unscoped) ? :unscoped : :with_exclusive_scope
|
19
|
+
if(self.class.rails_arel?)
|
20
|
+
self.class.configuration[:class].send(scope_strip_method) do
|
20
21
|
self.class.configuration[:class].from(
|
21
22
|
query
|
22
23
|
).order("#{self.class.configuration[:class].table_name}.depth DESC")
|
23
24
|
end
|
24
25
|
else
|
25
|
-
self.class.configuration[:class].send(
|
26
|
+
self.class.configuration[:class].send(scope_strip_method) do
|
26
27
|
self.class.configuration[:class].scoped(
|
27
28
|
:from => query,
|
28
29
|
:order => "#{self.class.configuration[:class].table_name}.depth DESC"
|
@@ -49,12 +50,12 @@ module ActsAsSaneTree
|
|
49
50
|
def self_and_siblings
|
50
51
|
parent ? parent.children : self.class.configuration[:class].roots
|
51
52
|
end
|
52
|
-
|
53
|
+
|
53
54
|
# Returns if the current node is a root
|
54
55
|
def root?
|
55
56
|
parent_id.nil?
|
56
57
|
end
|
57
|
-
|
58
|
+
|
58
59
|
# Returns all descendants of the current node. Each level
|
59
60
|
# is within its own hash, so for a structure like:
|
60
61
|
# root
|
@@ -63,9 +64,9 @@ module ActsAsSaneTree
|
|
63
64
|
# \_ subsubchild1
|
64
65
|
# \_ subchild2
|
65
66
|
# the resulting hash would look like:
|
66
|
-
#
|
67
|
-
# {child1 =>
|
68
|
-
# {subchild1 =>
|
67
|
+
#
|
68
|
+
# {child1 =>
|
69
|
+
# {subchild1 =>
|
69
70
|
# {subsubchild1 => {}},
|
70
71
|
# subchild2 => {}}}
|
71
72
|
#
|
@@ -79,16 +80,16 @@ module ActsAsSaneTree
|
|
79
80
|
self.class.configuration[:class].nodes_and_descendants(:no_self, self, *args)
|
80
81
|
end
|
81
82
|
alias_method :descendents, :descendants
|
82
|
-
|
83
|
+
|
83
84
|
# Returns the depth of the current node. 0 depth represents the root of the tree
|
84
85
|
def depth
|
85
|
-
query =
|
86
|
+
query =
|
86
87
|
"WITH RECURSIVE crumbs AS (
|
87
88
|
SELECT parent_id, 0 AS level
|
88
89
|
FROM #{self.class.configuration[:class].table_name}
|
89
|
-
WHERE id = #{self.id}
|
90
|
+
WHERE id = #{self.id}
|
90
91
|
UNION ALL
|
91
|
-
SELECT alias1.parent_id, level + 1
|
92
|
+
SELECT alias1.parent_id, level + 1
|
92
93
|
FROM crumbs
|
93
94
|
JOIN #{self.class.configuration[:class].table_name} alias1 ON alias1.id = crumbs.parent_id
|
94
95
|
) SELECT level FROM crumbs ORDER BY level DESC LIMIT 1"
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module ActsAsSaneTree
|
2
2
|
module SingletonMethods
|
3
|
-
|
3
|
+
|
4
4
|
# Check if we are in rails 3
|
5
|
-
def
|
6
|
-
@
|
5
|
+
def rails_arel?
|
6
|
+
@is_arel ||= !defined?(Arel).nil?
|
7
7
|
end
|
8
8
|
|
9
9
|
# Return all root nodes
|
10
10
|
def roots
|
11
|
-
if(
|
11
|
+
if(rails_arel?)
|
12
12
|
configuration[:class].where(
|
13
13
|
"#{configuration[:foreign_key]} IS NULL"
|
14
14
|
).order(configuration[:order])
|
@@ -22,12 +22,12 @@ module ActsAsSaneTree
|
|
22
22
|
|
23
23
|
# Return first root node
|
24
24
|
def root
|
25
|
-
if(
|
25
|
+
if(rails_arel?)
|
26
26
|
configuration[:class].where("#{configuration[:foreign_key]} IS NULL").order(configuration[:order]).first
|
27
27
|
else
|
28
28
|
configuration[:class].find(
|
29
|
-
:first,
|
30
|
-
:conditions => "#{configuration[:foreign_key]} IS NULL",
|
29
|
+
:first,
|
30
|
+
:conditions => "#{configuration[:foreign_key]} IS NULL",
|
31
31
|
:order => configuration[:order]
|
32
32
|
)
|
33
33
|
end
|
@@ -57,26 +57,26 @@ module ActsAsSaneTree
|
|
57
57
|
# chk:: Array of nodes
|
58
58
|
# Return all nodes that are within both chk and src
|
59
59
|
def nodes_within(src, chk)
|
60
|
-
s =
|
61
|
-
c =
|
60
|
+
s = [src].flatten.compact.map{|x|x.is_a?(ActiveRecord::Base) ? x.id : x.to_i}
|
61
|
+
c = [chk].flatten.compact.map{|x|x.is_a?(ActiveRecord::Base) ? x.id : x.to_i}
|
62
62
|
if(s.empty? || c.empty?)
|
63
63
|
nil
|
64
64
|
else
|
65
|
-
query =
|
65
|
+
query =
|
66
66
|
"(WITH RECURSIVE crumbs AS (
|
67
67
|
SELECT #{configuration[:class].table_name}.*, 0 AS depth FROM #{configuration[:class].table_name} WHERE id in (#{s.join(', ')})
|
68
68
|
UNION ALL
|
69
69
|
SELECT alias1.*, crumbs.depth + 1 FROM crumbs JOIN #{configuration[:class].table_name} alias1 on alias1.parent_id = crumbs.id
|
70
70
|
#{configuration[:max_depth] ? "WHERE crumbs.depth + 1 < #{configuration[:max_depth].to_i}" : ''}
|
71
71
|
) SELECT * FROM crumbs WHERE id in (#{c.join(', ')})) as #{configuration[:class].table_name}"
|
72
|
-
if(
|
72
|
+
if(rails_arel?)
|
73
73
|
configuration[:class].from(query)
|
74
74
|
else
|
75
75
|
configuration[:class].scoped(:from => query)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
# args:: ActiveRecord models or IDs - Symbols: :raw, :no_self - Hash: {:to_depth => n, :at_depth => n}
|
81
81
|
# Returns provided nodes plus all descendants of provided nodes in nested Hash where keys are nodes and values are children
|
82
82
|
# :raw:: return value will be flat array
|
@@ -104,7 +104,7 @@ module ActsAsSaneTree
|
|
104
104
|
depth_clause = "#{configuration[:class].table_name}.depth + 1 < #{depth.to_i + 2}"
|
105
105
|
end
|
106
106
|
base_ids = args.map{|x| x.is_a?(ActiveRecord::Base) ? x.id : x.to_i}
|
107
|
-
query =
|
107
|
+
query =
|
108
108
|
"(WITH RECURSIVE crumbs AS (
|
109
109
|
SELECT #{configuration[:class].table_name}.*, #{no_self ? -1 : 0} AS depth FROM #{configuration[:class].table_name} WHERE #{base_ids.empty? ? 'parent_id IS NULL' : "id in (#{base_ids.join(', ')})"}
|
110
110
|
UNION ALL
|
@@ -112,7 +112,7 @@ module ActsAsSaneTree
|
|
112
112
|
#{depth_restriction}
|
113
113
|
) SELECT * FROM crumbs) as #{configuration[:class].table_name}"
|
114
114
|
q = nil
|
115
|
-
if(
|
115
|
+
if(rails_arel?)
|
116
116
|
q = configuration[:class].from(
|
117
117
|
query
|
118
118
|
).where(
|
@@ -126,7 +126,7 @@ module ActsAsSaneTree
|
|
126
126
|
end
|
127
127
|
else
|
128
128
|
q = configuration[:class].scoped(
|
129
|
-
:from => query,
|
129
|
+
:from => query,
|
130
130
|
:conditions => "#{configuration[:class].table_name}.depth >= 0"
|
131
131
|
)
|
132
132
|
if(configuration[:order].present?)
|
@@ -136,7 +136,7 @@ module ActsAsSaneTree
|
|
136
136
|
q = q.scoped(:conditions => depth_clause)
|
137
137
|
end
|
138
138
|
end
|
139
|
-
unless(
|
139
|
+
unless(rails_arel?)
|
140
140
|
q = q.scoped(scope(:find))
|
141
141
|
end
|
142
142
|
unless(raw)
|
metadata
CHANGED
@@ -1,89 +1,68 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_sane_tree
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 2
|
8
|
-
- 0
|
9
|
-
- 5
|
10
|
-
version: 2.0.5
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.6
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Chris Roberts
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2014-11-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
22
14
|
name: activerecord
|
23
|
-
|
24
|
-
|
25
|
-
none: false
|
26
|
-
requirements:
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
27
17
|
- - ">"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
33
20
|
type: :runtime
|
34
|
-
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
35
27
|
description: Sane ActiveRecord tree builder
|
36
28
|
email: chrisroberts.code@gmail.com
|
37
29
|
executables: []
|
38
|
-
|
39
30
|
extensions: []
|
40
|
-
|
41
|
-
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
files:
|
34
|
+
- CHANGELOG.rdoc
|
42
35
|
- README.rdoc
|
43
|
-
files:
|
44
36
|
- acts_as_sane_tree.gemspec
|
45
37
|
- init.rb
|
46
|
-
- README.rdoc
|
47
|
-
- CHANGELOG.rdoc
|
48
38
|
- lib/acts_as_sane_tree.rb
|
49
|
-
- lib/acts_as_sane_tree/version.rb
|
50
39
|
- lib/acts_as_sane_tree/acts_as_sane_tree.rb
|
51
|
-
- lib/acts_as_sane_tree/singleton_methods.rb
|
52
40
|
- lib/acts_as_sane_tree/instance_methods.rb
|
41
|
+
- lib/acts_as_sane_tree/singleton_methods.rb
|
42
|
+
- lib/acts_as_sane_tree/version.rb
|
53
43
|
- rails/init.rb
|
54
|
-
has_rdoc: true
|
55
44
|
homepage: http://github.com/chrisroberts/acts_as_sane_tree
|
56
45
|
licenses: []
|
57
|
-
|
46
|
+
metadata: {}
|
58
47
|
post_install_message:
|
59
48
|
rdoc_options: []
|
60
|
-
|
61
|
-
require_paths:
|
49
|
+
require_paths:
|
62
50
|
- lib
|
63
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
-
|
65
|
-
requirements:
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
66
53
|
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
version: "0"
|
72
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
|
-
requirements:
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
75
58
|
- - ">="
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
|
78
|
-
segments:
|
79
|
-
- 0
|
80
|
-
version: "0"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
81
61
|
requirements: []
|
82
|
-
|
83
62
|
rubyforge_project:
|
84
|
-
rubygems_version:
|
63
|
+
rubygems_version: 2.2.2
|
85
64
|
signing_key:
|
86
|
-
specification_version:
|
65
|
+
specification_version: 4
|
87
66
|
summary: Sane tree builder for ActiveRecord and Postgresql
|
88
67
|
test_files: []
|
89
|
-
|
68
|
+
has_rdoc: true
|