acts-as-tree-with-dotted-ids 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/active_record/acts/tree_with_dotted_ids.rb +33 -33
- metadata +22 -42
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 87759d6b94e64e5e78f4c513083c64fa1cc0e673
|
4
|
+
data.tar.gz: 735fcbcbb7b7d575b9a8a0c5e60a39eac0ed9530
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 209c4fd3d1640701cc988b1ea61ce0c42985f7aea6f551fd6a236d8e784918475e65dd803f4824cdea8760d3b05485017908f2bac89fefad8a8c0c40bdbf2215
|
7
|
+
data.tar.gz: 64dd80ad140616a0fc443ab87b27e19d72e00a8a3265c6c5fb3511873ddb70f2e4762b8092006ff064f2a27b813cca739aa1473ad63d3e0ee0ea55a9a7915ba2
|
@@ -39,7 +39,7 @@ module ActiveRecord
|
|
39
39
|
# The following class methods are added
|
40
40
|
# * <tt>traverse</tt> - depth-first traversal of the tree (warning: it does *not* rely on the dotted_ids as it is used to rebuild the tree)
|
41
41
|
# * <tt>rebuild_dotted_ids!</tt> - rebuilt the dotted IDs for the whole tree, use this once to migrate an existing +acts_as_tree+ model to +acts_as_tree_with_dotted_ids+
|
42
|
-
|
42
|
+
|
43
43
|
module ClassMethods
|
44
44
|
# Configuration options are:
|
45
45
|
#
|
@@ -51,10 +51,10 @@ module ActiveRecord
|
|
51
51
|
configuration.update(options) if options.is_a?(Hash)
|
52
52
|
|
53
53
|
belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
|
54
|
-
|
55
54
|
|
56
|
-
|
57
|
-
|
55
|
+
|
56
|
+
has_many :children, -> { order(configuration[:order]) }, :class_name => name, :foreign_key => configuration[:foreign_key],
|
57
|
+
:dependent => :destroy, &b
|
58
58
|
|
59
59
|
after_save :assign_dotted_ids
|
60
60
|
after_validation :update_dotted_ids, :on => :update
|
@@ -63,22 +63,22 @@ module ActiveRecord
|
|
63
63
|
include ActiveRecord::Acts::TreeWithDottedIds::InstanceMethods
|
64
64
|
|
65
65
|
def self.roots
|
66
|
-
res =
|
66
|
+
res = where("#{configuration[:foreign_key]} IS NULL").order(#{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
|
67
67
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def self.root
|
71
|
-
|
71
|
+
where("#{configuration[:foreign_key]} IS NULL").order(#{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}).first
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
def parent_foreign_key_changed?
|
75
75
|
#{configuration[:foreign_key]}_changed?
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
EOV
|
79
79
|
end
|
80
|
-
|
81
|
-
# Performs a depth-first traversal of the tree, yielding each node to the given block
|
80
|
+
|
81
|
+
# Performs a depth-first traversal of the tree, yielding each node to the given block
|
82
82
|
def traverse(nodes = nil, &block)
|
83
83
|
nodes ||= self.roots
|
84
84
|
nodes.each do |node|
|
@@ -86,7 +86,7 @@ module ActiveRecord
|
|
86
86
|
traverse(node.children, &block)
|
87
87
|
end
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
# Traverse the whole tree from roots to leaves and rebuild the dotted_ids path
|
91
91
|
# Call it from your migration to upgrade an existing acts_as_tree model.
|
92
92
|
def rebuild_dotted_ids!
|
@@ -94,7 +94,7 @@ module ActiveRecord
|
|
94
94
|
traverse { |node| node.dotted_ids = nil; node.save! }
|
95
95
|
end
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
end
|
99
99
|
|
100
100
|
module InstanceMethods
|
@@ -105,15 +105,15 @@ module ActiveRecord
|
|
105
105
|
def ancestors
|
106
106
|
if self.dotted_ids
|
107
107
|
ids = self.dotted_ids.split('.')[0...-1]
|
108
|
-
self.class.
|
108
|
+
self.class.where(:id => ids).order('dotted_ids DESC')
|
109
109
|
else
|
110
110
|
node, nodes = self, []
|
111
111
|
nodes << node = node.parent while node.parent
|
112
112
|
nodes
|
113
113
|
end
|
114
114
|
end
|
115
|
-
|
116
|
-
#
|
115
|
+
|
116
|
+
#
|
117
117
|
def self_and_ancestors
|
118
118
|
[self] + ancestors
|
119
119
|
end
|
@@ -141,35 +141,35 @@ module ActiveRecord
|
|
141
141
|
# subchild1.self_and_siblings # => [subchild1, subchild2]
|
142
142
|
def self_and_siblings
|
143
143
|
#parent ? parent.children : self.class.roots
|
144
|
-
self.class.
|
144
|
+
self.class.where(:parent_id => self.parent_id)
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
#
|
148
148
|
# root.ancestor_of?(subchild1) # => true
|
149
149
|
# subchild1.ancestor_of?(child1) # => false
|
150
150
|
def ancestor_of?(node)
|
151
151
|
node.dotted_ids.length > self.dotted_ids.length && node.dotted_ids.starts_with?(self.dotted_ids)
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
#
|
155
155
|
# subchild1.descendant_of?(child1) # => true
|
156
156
|
# root.descendant_of?(subchild1) # => false
|
157
157
|
def descendant_of?(node)
|
158
158
|
self.dotted_ids.length > node.dotted_ids.length && self.dotted_ids.starts_with?(node.dotted_ids)
|
159
159
|
end
|
160
|
-
|
160
|
+
|
161
161
|
# Returns all children of the current node
|
162
162
|
# root.all_children # => [child1, subchild1, subchild2]
|
163
163
|
def all_children
|
164
164
|
find_all_children_with_dotted_ids
|
165
165
|
end
|
166
|
-
|
166
|
+
|
167
167
|
# Returns all children of the current node
|
168
168
|
# root.self_and_all_children # => [root, child1, subchild1, subchild2]
|
169
169
|
def self_and_all_children
|
170
170
|
[self] + all_children
|
171
171
|
end
|
172
|
-
|
172
|
+
|
173
173
|
# Returns the depth of the node, root nodes have a depth of 0
|
174
174
|
def depth
|
175
175
|
if self.dotted_ids.present?
|
@@ -178,44 +178,44 @@ module ActiveRecord
|
|
178
178
|
(self.parent.try(:depth) || -1) + 1
|
179
179
|
end
|
180
180
|
end
|
181
|
-
|
181
|
+
|
182
182
|
protected
|
183
|
-
|
183
|
+
|
184
184
|
# Tranforms a dotted_id string into a pattern usable with a SQL LIKE statement
|
185
185
|
def dotted_id_like_pattern(prefix = nil)
|
186
186
|
(prefix || self.dotted_ids) + '.%'
|
187
187
|
end
|
188
|
-
|
188
|
+
|
189
189
|
# Find all children with the given dotted_id prefix
|
190
|
-
# *
|
191
|
-
# FIXME: use
|
192
|
-
def find_all_children_with_dotted_ids(prefix = nil,
|
193
|
-
|
190
|
+
# *extra_scope* will be combine with dotted_ids LIKE
|
191
|
+
# FIXME: use extra_scope when it will be part of the public API
|
192
|
+
def find_all_children_with_dotted_ids(prefix = nil, extra_scope = self.class.where('1=1'))
|
193
|
+
extra_scope.where('dotted_ids LIKE ?', dotted_id_like_pattern(prefix))
|
194
194
|
end
|
195
|
-
|
195
|
+
|
196
196
|
# Generates the dotted_ids for this node
|
197
197
|
def build_dotted_ids
|
198
198
|
self.parent ? "#{self.parent.dotted_ids}.#{self.id}" : self.id.to_s
|
199
199
|
end
|
200
|
-
|
200
|
+
|
201
201
|
# After create, adds the dotted id's
|
202
202
|
def assign_dotted_ids
|
203
203
|
self.update_attribute(:dotted_ids, build_dotted_ids) if self.dotted_ids.blank?
|
204
204
|
end
|
205
|
-
|
205
|
+
|
206
206
|
# After validation on update, rebuild dotted ids if necessary
|
207
207
|
def update_dotted_ids
|
208
208
|
return unless parent_foreign_key_changed?
|
209
209
|
old_dotted_ids = self.dotted_ids
|
210
210
|
old_dotted_ids_regex = Regexp.new("^#{Regexp.escape(old_dotted_ids)}(.*)")
|
211
211
|
self.dotted_ids = build_dotted_ids
|
212
|
-
replace_pattern = "#{self.dotted_ids}\\1"
|
212
|
+
replace_pattern = "#{self.dotted_ids}\\1"
|
213
213
|
find_all_children_with_dotted_ids(old_dotted_ids).each do |node|
|
214
214
|
new_dotted_ids = node.dotted_ids.gsub(old_dotted_ids_regex, replace_pattern)
|
215
215
|
node.update_attribute(:dotted_ids, new_dotted_ids)
|
216
216
|
end
|
217
217
|
end
|
218
|
-
|
218
|
+
|
219
219
|
end
|
220
220
|
end
|
221
221
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts-as-tree-with-dotted-ids
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- David Heinemeier Hansson
|
@@ -10,72 +9,56 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2015-02-10 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: activerecord
|
17
|
-
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
|
-
requirements:
|
20
|
-
- - ! '>='
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 3.0.0
|
23
|
-
type: :runtime
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
|
-
requirements:
|
28
|
-
- - ! '>='
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: 3.0.0
|
31
14
|
- !ruby/object:Gem::Dependency
|
32
15
|
name: jeweler
|
33
16
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
17
|
requirements:
|
36
|
-
- -
|
18
|
+
- - "~>"
|
37
19
|
- !ruby/object:Gem::Version
|
38
20
|
version: '0'
|
39
21
|
type: :development
|
40
22
|
prerelease: false
|
41
23
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
24
|
requirements:
|
44
|
-
- -
|
25
|
+
- - "~>"
|
45
26
|
- !ruby/object:Gem::Version
|
46
27
|
version: '0'
|
47
28
|
- !ruby/object:Gem::Dependency
|
48
29
|
name: sqlite3
|
49
30
|
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
31
|
requirements:
|
52
|
-
- -
|
32
|
+
- - "~>"
|
53
33
|
- !ruby/object:Gem::Version
|
54
34
|
version: '0'
|
55
35
|
type: :development
|
56
36
|
prerelease: false
|
57
37
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
38
|
requirements:
|
60
|
-
- -
|
39
|
+
- - "~>"
|
61
40
|
- !ruby/object:Gem::Version
|
62
41
|
version: '0'
|
63
42
|
- !ruby/object:Gem::Dependency
|
64
43
|
name: activerecord
|
65
44
|
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
45
|
requirements:
|
68
|
-
- -
|
46
|
+
- - ">="
|
69
47
|
- !ruby/object:Gem::Version
|
70
48
|
version: 3.0.0
|
49
|
+
- - "~>"
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '3.0'
|
71
52
|
type: :runtime
|
72
53
|
prerelease: false
|
73
54
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
55
|
requirements:
|
76
|
-
- -
|
56
|
+
- - ">="
|
77
57
|
- !ruby/object:Gem::Version
|
78
58
|
version: 3.0.0
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
79
62
|
description: ''
|
80
63
|
email: tma@freshbit.ch
|
81
64
|
executables: []
|
@@ -83,35 +66,32 @@ extensions: []
|
|
83
66
|
extra_rdoc_files:
|
84
67
|
- README.rdoc
|
85
68
|
files:
|
69
|
+
- README.rdoc
|
86
70
|
- lib/active_record/acts/tree_with_dotted_ids.rb
|
87
71
|
- lib/acts-as-tree-with-dotted-ids.rb
|
88
|
-
- README.rdoc
|
89
72
|
homepage: http://github.com/tma/acts-as-tree-with-dotted-ids
|
90
|
-
licenses:
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
91
76
|
post_install_message:
|
92
77
|
rdoc_options: []
|
93
78
|
require_paths:
|
94
79
|
- lib
|
95
80
|
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
-
none: false
|
97
81
|
requirements:
|
98
|
-
- -
|
82
|
+
- - ">="
|
99
83
|
- !ruby/object:Gem::Version
|
100
84
|
version: '0'
|
101
|
-
segments:
|
102
|
-
- 0
|
103
|
-
hash: 1326598496013907944
|
104
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
86
|
requirements:
|
107
|
-
- -
|
87
|
+
- - ">="
|
108
88
|
- !ruby/object:Gem::Version
|
109
89
|
version: '0'
|
110
90
|
requirements: []
|
111
91
|
rubyforge_project:
|
112
|
-
rubygems_version:
|
92
|
+
rubygems_version: 2.4.5
|
113
93
|
signing_key:
|
114
|
-
specification_version:
|
94
|
+
specification_version: 4
|
115
95
|
summary: A drop in replacement for acts_as_tree with super fast ancestors and subtree
|
116
96
|
access
|
117
97
|
test_files: []
|