mongoid-ancestry-fixes 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- metadata +11 -34
- data/.gitignore +0 -42
- data/.travis.yml +0 -3
- data/Gemfile +0 -8
- data/Gemfile.lock +0 -47
- data/Guardfile +0 -10
- data/MIT-LICENSE +0 -20
- data/Rakefile +0 -21
- data/init.rb +0 -1
- data/install.rb +0 -1
- data/lib/mongoid-ancestry.rb +0 -15
- data/lib/mongoid-ancestry/class_methods.rb +0 -212
- data/lib/mongoid-ancestry/exceptions.rb +0 -6
- data/lib/mongoid-ancestry/instance_methods.rb +0 -248
- data/lib/mongoid-ancestry/version.rb +0 -5
- data/log/.gitignore +0 -4
- data/mongoid-ancestry.gemspec +0 -29
- data/spec/lib/ancestry_spec.rb +0 -110
- data/spec/lib/mongoid-ancestry/class_methods_spec.rb +0 -300
- data/spec/lib/mongoid-ancestry/instance_methods_spec.rb +0 -241
- data/spec/spec_helper.rb +0 -22
- data/spec/support/models.rb +0 -40
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZmM5YTM5MDAwNjg4NmRhYzRlNzEzOTY4YmMzYjgzODhhMTMzYTJkMQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjZiMWQ3MTU4NzZkNWExNmU4YTY4NzVkNzI0YzI4MzEwOWRiNjNiOQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NTdlNmUxYWFkZmNkMTU5ZjkxZWQ5MDM4ZTFkMzk5NDczYjE2NmFmZTJjMWUy
|
10
|
+
OWRiMWQxNzMwMGEwZWNiNGU1N2JhY2IyM2Q3NGNkY2EyMDI1NGVkNzcxMGI5
|
11
|
+
ZDEwZjlhMzgzY2MxNGI5NjZhMWM3YzNmNjhmYWE5MWVjMjJhNGM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YmRjNDQwMjIyMWUyYWM4OWJjZTdhN2VjNzc1YmU1ZDEzMGYwOWMwZjA3YTRi
|
14
|
+
NGFkNDUyOGQ1YTk2MzFkNGVmNzk4YTZkMDQ0YzI2MDQzNWUyMmNmNTFhODg2
|
15
|
+
ZDg0NTM1YTFkNGRmYjJhZTY0ZWJmNTAwY2UxZTdjNzQ3M2E4ZDI=
|
metadata
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-ancestry-fixes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Kroes
|
8
8
|
- Anton Orel
|
9
|
+
- fl00r
|
10
|
+
- shilovk
|
9
11
|
autorequire:
|
10
12
|
bindir: bin
|
11
13
|
cert_chain: []
|
@@ -47,28 +49,7 @@ extensions: []
|
|
47
49
|
extra_rdoc_files:
|
48
50
|
- README.md
|
49
51
|
files:
|
50
|
-
- .gitignore
|
51
|
-
- .travis.yml
|
52
|
-
- Gemfile
|
53
|
-
- Gemfile.lock
|
54
|
-
- Guardfile
|
55
|
-
- MIT-LICENSE
|
56
52
|
- README.md
|
57
|
-
- Rakefile
|
58
|
-
- init.rb
|
59
|
-
- install.rb
|
60
|
-
- lib/mongoid-ancestry.rb
|
61
|
-
- lib/mongoid-ancestry/class_methods.rb
|
62
|
-
- lib/mongoid-ancestry/exceptions.rb
|
63
|
-
- lib/mongoid-ancestry/instance_methods.rb
|
64
|
-
- lib/mongoid-ancestry/version.rb
|
65
|
-
- log/.gitignore
|
66
|
-
- mongoid-ancestry.gemspec
|
67
|
-
- spec/lib/ancestry_spec.rb
|
68
|
-
- spec/lib/mongoid-ancestry/class_methods_spec.rb
|
69
|
-
- spec/lib/mongoid-ancestry/instance_methods_spec.rb
|
70
|
-
- spec/spec_helper.rb
|
71
|
-
- spec/support/models.rb
|
72
53
|
homepage: http://github.com/skyeagle/mongoid-ancestry
|
73
54
|
licenses:
|
74
55
|
- MIT
|
@@ -92,15 +73,11 @@ rubyforge_project: mongoid-ancestry-fixes
|
|
92
73
|
rubygems_version: 2.4.5
|
93
74
|
signing_key:
|
94
75
|
specification_version: 4
|
95
|
-
summary:
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
- spec/lib/mongoid-ancestry/class_methods_spec.rb
|
104
|
-
- spec/lib/mongoid-ancestry/instance_methods_spec.rb
|
105
|
-
- spec/spec_helper.rb
|
106
|
-
- spec/support/models.rb
|
76
|
+
summary: This is a fork of mongoid-ancestry-0.2.3 with some fixes. Ancestry allows
|
77
|
+
the records of a Mongoid model to be organised in a tree structure, using a single,
|
78
|
+
intuitively formatted database field. It exposes all the standard tree structure
|
79
|
+
relations (ancestors, parent, root, children, siblings, descendants) and all of
|
80
|
+
them can be fetched in a single query. Additional features are named_scopes, integrity
|
81
|
+
checking, integrity restoration, arrangement of (sub)tree into hashes and different
|
82
|
+
strategies for dealing with orphaned records.
|
83
|
+
test_files: []
|
data/.gitignore
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
# rcov generated
|
2
|
-
coverage
|
3
|
-
|
4
|
-
# rdoc generated
|
5
|
-
rdoc
|
6
|
-
|
7
|
-
# yard generated
|
8
|
-
doc
|
9
|
-
.yardoc
|
10
|
-
|
11
|
-
# bundler
|
12
|
-
.bundle
|
13
|
-
|
14
|
-
# jeweler generated
|
15
|
-
pkg
|
16
|
-
|
17
|
-
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
18
|
-
#
|
19
|
-
# * Create a file at ~/.gitignore
|
20
|
-
# * Include files you want ignored
|
21
|
-
# * Run: git config --global core.excludesfile ~/.gitignore
|
22
|
-
#
|
23
|
-
# After doing this, these files will be ignored in all your git projects,
|
24
|
-
# saving you from having to 'pollute' every project you touch with them
|
25
|
-
#
|
26
|
-
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
27
|
-
#
|
28
|
-
# For MacOS:
|
29
|
-
#
|
30
|
-
#.DS_Store
|
31
|
-
#
|
32
|
-
# For TextMate
|
33
|
-
#*.tmproj
|
34
|
-
#tmtags
|
35
|
-
#
|
36
|
-
# For emacs:
|
37
|
-
#*~
|
38
|
-
#\#*
|
39
|
-
#.\#*
|
40
|
-
#
|
41
|
-
# For vim:
|
42
|
-
#*.swp
|
data/.travis.yml
DELETED
data/Gemfile
DELETED
data/Gemfile.lock
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
mongoid-ancestry (0.2.3)
|
5
|
-
bson_ext (>= 1.3)
|
6
|
-
mongoid (>= 2.0)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: http://rubygems.org/
|
10
|
-
specs:
|
11
|
-
activemodel (3.2.5)
|
12
|
-
activesupport (= 3.2.5)
|
13
|
-
builder (~> 3.0.0)
|
14
|
-
activesupport (3.2.5)
|
15
|
-
i18n (~> 0.6)
|
16
|
-
multi_json (~> 1.0)
|
17
|
-
bson (1.6.4)
|
18
|
-
bson_ext (1.6.4)
|
19
|
-
bson (~> 1.6.4)
|
20
|
-
builder (3.0.0)
|
21
|
-
diff-lcs (1.1.2)
|
22
|
-
i18n (0.6.0)
|
23
|
-
mongo (1.6.2)
|
24
|
-
bson (~> 1.6.2)
|
25
|
-
mongoid (2.4.7)
|
26
|
-
activemodel (~> 3.1)
|
27
|
-
mongo (~> 1.3)
|
28
|
-
tzinfo (~> 0.3.22)
|
29
|
-
multi_json (1.3.6)
|
30
|
-
rake (0.9.2.2)
|
31
|
-
rspec (2.5.0)
|
32
|
-
rspec-core (~> 2.5.0)
|
33
|
-
rspec-expectations (~> 2.5.0)
|
34
|
-
rspec-mocks (~> 2.5.0)
|
35
|
-
rspec-core (2.5.1)
|
36
|
-
rspec-expectations (2.5.0)
|
37
|
-
diff-lcs (~> 1.1.2)
|
38
|
-
rspec-mocks (2.5.0)
|
39
|
-
tzinfo (0.3.33)
|
40
|
-
|
41
|
-
PLATFORMS
|
42
|
-
ruby
|
43
|
-
|
44
|
-
DEPENDENCIES
|
45
|
-
mongoid-ancestry!
|
46
|
-
rake
|
47
|
-
rspec (~> 2.5)
|
data/Guardfile
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
# A sample Guardfile
|
2
|
-
# More info at https://github.com/guard/guard#readme
|
3
|
-
|
4
|
-
guard 'rspec', :version => 2, :cli => "--format Fuubar" do
|
5
|
-
watch(%r{^spec/.+_spec\.rb})
|
6
|
-
watch(%r{^lib/mongoid-ancestry/(.+)\.rb}) { |m| "spec/lib/mongoid-ancestry/#{m[1]}_spec.rb" }
|
7
|
-
watch('lib/mongoid-ancestry.rb') { "spec" }
|
8
|
-
watch(%r{^spec/support/(.+)\.rb}) { "spec" }
|
9
|
-
watch('spec/spec_helper.rb') { "spec" }
|
10
|
-
end
|
data/MIT-LICENSE
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
Copyright (c) 2009 Stefan Kroes
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
Bundler.setup
|
3
|
-
Bundler::GemHelper.install_tasks
|
4
|
-
|
5
|
-
require 'rspec/core'
|
6
|
-
require 'rspec/core/rake_task'
|
7
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
8
|
-
spec.pattern = FileList['spec/**/*_spec.rb']
|
9
|
-
end
|
10
|
-
|
11
|
-
task :default => :spec
|
12
|
-
|
13
|
-
require 'rdoc/task'
|
14
|
-
Rake::RDocTask.new do |rdoc|
|
15
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
16
|
-
|
17
|
-
rdoc.rdoc_dir = 'rdoc'
|
18
|
-
rdoc.title = "mongoid-ancestry #{version}"
|
19
|
-
rdoc.rdoc_files.include('README*')
|
20
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
-
end
|
data/init.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'ancestry'
|
data/install.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
puts "Thank you for installing Ancestry. You can visit http://github.com/stefankroes/ancestry to read the documentation."
|
data/lib/mongoid-ancestry.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
module Mongoid
|
2
|
-
module Ancestry
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
autoload :ClassMethods, 'mongoid-ancestry/class_methods'
|
6
|
-
autoload :Error, 'mongoid-ancestry/exceptions'
|
7
|
-
|
8
|
-
included do
|
9
|
-
cattr_accessor :base_class
|
10
|
-
self.base_class = self
|
11
|
-
end
|
12
|
-
|
13
|
-
require 'mongoid-ancestry/instance_methods'
|
14
|
-
end
|
15
|
-
end
|
@@ -1,212 +0,0 @@
|
|
1
|
-
module Mongoid
|
2
|
-
module Ancestry
|
3
|
-
module ClassMethods
|
4
|
-
def has_ancestry(opts = {})
|
5
|
-
defaults = {
|
6
|
-
:ancestry_field => :ancestry,
|
7
|
-
:cache_depth => false,
|
8
|
-
:depth_cache_field => :ancestry_depth,
|
9
|
-
:orphan_strategy => :destroy
|
10
|
-
}
|
11
|
-
|
12
|
-
valid_opts = [:ancestry_field, :cache_depth, :depth_cache_field, :orphan_strategy]
|
13
|
-
unless opts.is_a?(Hash) && opts.keys.all? {|opt| valid_opts.include?(opt) }
|
14
|
-
raise Error.new("Invalid options for has_ancestry. Only hash is allowed.\n Defaults: #{defaults.inspect}")
|
15
|
-
end
|
16
|
-
|
17
|
-
opts.symbolize_keys!
|
18
|
-
|
19
|
-
opts.reverse_merge!(defaults)
|
20
|
-
|
21
|
-
# Create ancestry field accessor and set to option or default
|
22
|
-
cattr_accessor :ancestry_field
|
23
|
-
self.ancestry_field = opts[:ancestry_field]
|
24
|
-
|
25
|
-
self.field ancestry_field, :type => String
|
26
|
-
self.index ancestry_field
|
27
|
-
|
28
|
-
# Create orphan strategy accessor and set to option or default (writer comes from DynamicClassMethods)
|
29
|
-
cattr_reader :orphan_strategy
|
30
|
-
self.orphan_strategy = opts[:orphan_strategy]
|
31
|
-
|
32
|
-
# Validate format of ancestry column value
|
33
|
-
primary_key_format = opts[:primary_key_format] || /[a-z0-9]+/
|
34
|
-
validates_format_of ancestry_field, :with => /\A#{primary_key_format.source}(\/#{primary_key_format.source})*\Z/, :allow_nil => true
|
35
|
-
|
36
|
-
# Validate that the ancestor ids don't include own id
|
37
|
-
validate :ancestry_exclude_self
|
38
|
-
|
39
|
-
# Create ancestry column accessor and set to option or default
|
40
|
-
if opts[:cache_depth]
|
41
|
-
# Create accessor for column name and set to option or default
|
42
|
-
self.cattr_accessor :depth_cache_field
|
43
|
-
self.depth_cache_field = opts[:depth_cache_field]
|
44
|
-
|
45
|
-
# Cache depth in depth cache column before save
|
46
|
-
before_validation :cache_depth
|
47
|
-
|
48
|
-
# Validate depth column
|
49
|
-
validates_numericality_of depth_cache_field, :greater_than_or_equal_to => 0, :only_integer => true, :allow_nil => false
|
50
|
-
end
|
51
|
-
|
52
|
-
# Create named scopes for depth
|
53
|
-
{:before_depth => 'lt', :to_depth => 'lte', :at_depth => nil, :from_depth => 'gte', :after_depth => 'gt'}.each do |scope_name, operator|
|
54
|
-
scope scope_name, lambda { |depth|
|
55
|
-
raise Error.new("Named scope '#{scope_name}' is only available when depth caching is enabled.") unless opts[:cache_depth]
|
56
|
-
where( (operator ? depth_cache_field.send(operator.to_sym) : depth_cache_field) => depth)
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
scope :roots, where(ancestry_field => nil)
|
61
|
-
scope :ancestors_of, lambda { |object| where(to_node(object).ancestor_conditions) }
|
62
|
-
scope :children_of, lambda { |object| where(to_node(object).child_conditions) }
|
63
|
-
scope :descendants_of, lambda { |object| any_of(to_node(object).descendant_conditions) }
|
64
|
-
scope :subtree_of, lambda { |object| any_of(to_node(object).subtree_conditions) }
|
65
|
-
scope :siblings_of, lambda { |object| where(to_node(object).sibling_conditions) }
|
66
|
-
scope :ordered_by_ancestry, asc(:"#{self.base_class.ancestry_field}")
|
67
|
-
scope :ordered_by_ancestry_and, lambda {|by| ordered_by_ancestry.order_by([by]) }
|
68
|
-
|
69
|
-
# Update descendants with new ancestry before save
|
70
|
-
before_save :update_descendants_with_new_ancestry
|
71
|
-
|
72
|
-
# Apply orphan strategy before destroy
|
73
|
-
before_destroy :apply_orphan_strategy
|
74
|
-
end
|
75
|
-
|
76
|
-
# Fetch tree node if necessary
|
77
|
-
def to_node object
|
78
|
-
object.is_a?(self.base_class) ? object : find(object)
|
79
|
-
end
|
80
|
-
|
81
|
-
# Scope on relative depth options
|
82
|
-
def scope_depth depth_options, depth
|
83
|
-
depth_options.inject(self.base_class) do |scope, option|
|
84
|
-
scope_name, relative_depth = option
|
85
|
-
if [:before_depth, :to_depth, :at_depth, :from_depth, :after_depth].include? scope_name
|
86
|
-
scope.send scope_name, depth + relative_depth
|
87
|
-
else
|
88
|
-
raise Error.new("Unknown depth option: #{scope_name}.")
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
# Orphan strategy writer
|
94
|
-
def orphan_strategy= orphan_strategy
|
95
|
-
# Check value of orphan strategy, only rootify, restrict or destroy is allowed
|
96
|
-
if [:rootify, :restrict, :destroy].include? orphan_strategy
|
97
|
-
class_variable_set :@@orphan_strategy, orphan_strategy
|
98
|
-
else
|
99
|
-
raise Error.new("Invalid orphan strategy, valid ones are :rootify, :restrict and :destroy.")
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# Arrangement
|
104
|
-
def arrange options = {}
|
105
|
-
scope =
|
106
|
-
if options[:order].nil?
|
107
|
-
self.base_class.ordered_by_ancestry
|
108
|
-
else
|
109
|
-
self.base_class.ordered_by_ancestry_and options.delete(:order)
|
110
|
-
end
|
111
|
-
# Get all nodes ordered by ancestry and start sorting them into an empty hash
|
112
|
-
scope.all(options).inject(ActiveSupport::OrderedHash.new) do |arranged_nodes, node|
|
113
|
-
# Find the insertion point for that node by going through its ancestors
|
114
|
-
node.ancestor_ids.inject(arranged_nodes) do |insertion_point, ancestor_id|
|
115
|
-
insertion_point.each do |parent, children|
|
116
|
-
# Change the insertion point to children if node is a descendant of this parent
|
117
|
-
insertion_point = children if ancestor_id == parent.id
|
118
|
-
end; insertion_point
|
119
|
-
end[node] = ActiveSupport::OrderedHash.new; arranged_nodes
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# Integrity checking
|
124
|
-
def check_ancestry_integrity! options = {}
|
125
|
-
parents = {}
|
126
|
-
exceptions = [] if options[:report] == :list
|
127
|
-
# For each node ...
|
128
|
-
self.base_class.all.each do |node|
|
129
|
-
begin
|
130
|
-
# ... check validity of ancestry column
|
131
|
-
if !node.valid? and !node.errors[node.class.ancestry_field].blank?
|
132
|
-
raise IntegrityError.new "Invalid format for ancestry column of node #{node.id}: #{node.read_attribute node.ancestry_field}."
|
133
|
-
end
|
134
|
-
# ... check that all ancestors exist
|
135
|
-
node.ancestor_ids.each do |ancestor_id|
|
136
|
-
unless where(:_id => ancestor_id).first
|
137
|
-
raise IntegrityError.new "Reference to non-existent node in node #{node.id}: #{ancestor_id}."
|
138
|
-
end
|
139
|
-
end
|
140
|
-
# ... check that all node parents are consistent with values observed earlier
|
141
|
-
node.path_ids.zip([nil] + node.path_ids).each do |node_id, parent_id|
|
142
|
-
parents[node_id] = parent_id unless parents.has_key? node_id
|
143
|
-
unless parents[node_id] == parent_id
|
144
|
-
raise IntegrityError.new "Conflicting parent id found in node #{node.id}: #{parent_id || 'nil'} for node #{node_id} while expecting #{parents[node_id] || 'nil'}"
|
145
|
-
end
|
146
|
-
end
|
147
|
-
rescue IntegrityError => integrity_exception
|
148
|
-
case options[:report]
|
149
|
-
when :list then exceptions << integrity_exception
|
150
|
-
when :echo then puts integrity_exception
|
151
|
-
else raise integrity_exception
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
exceptions if options[:report] == :list
|
156
|
-
end
|
157
|
-
|
158
|
-
# Integrity restoration
|
159
|
-
def restore_ancestry_integrity!
|
160
|
-
parents = {}
|
161
|
-
# For each node ...
|
162
|
-
self.base_class.all.each do |node|
|
163
|
-
# ... set its ancestry to nil if invalid
|
164
|
-
if node.errors[node.class.ancestry_field].blank?
|
165
|
-
node.without_ancestry_callbacks do
|
166
|
-
node.update_attribute node.ancestry_field, nil
|
167
|
-
end
|
168
|
-
end
|
169
|
-
# ... save parent of this node in parents array if it exists
|
170
|
-
parents[node.id] = node.parent_id if exists? node.parent_id
|
171
|
-
|
172
|
-
# Reset parent id in array to nil if it introduces a cycle
|
173
|
-
parent = parents[node.id]
|
174
|
-
until parent.nil? || parent == node.id
|
175
|
-
parent = parents[parent]
|
176
|
-
end
|
177
|
-
parents[node.id] = nil if parent == node.id
|
178
|
-
end
|
179
|
-
# For each node ...
|
180
|
-
self.base_class.all.each do |node|
|
181
|
-
# ... rebuild ancestry from parents array
|
182
|
-
ancestry, parent = nil, parents[node.id]
|
183
|
-
until parent.nil?
|
184
|
-
ancestry, parent = if ancestry.nil? then parent else "#{parent}/#{ancestry}" end, parents[parent]
|
185
|
-
end
|
186
|
-
node.without_ancestry_callbacks do
|
187
|
-
node.update_attribute node.ancestry_field, ancestry
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
# Build ancestry from parent id's for migration purposes
|
193
|
-
def build_ancestry_from_parent_ids! parent_id = nil, ancestry = nil
|
194
|
-
self.base_class.where(:parent_id => parent_id).all.each do |node|
|
195
|
-
node.without_ancestry_callbacks do
|
196
|
-
node.update_attribute(self.base_class.ancestry_field, ancestry)
|
197
|
-
end
|
198
|
-
build_ancestry_from_parent_ids! node.id,
|
199
|
-
if ancestry.nil? then node.id.to_s else "#{ancestry}/#{node.id}" end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
# Rebuild depth cache if it got corrupted or if depth caching was just turned on
|
204
|
-
def rebuild_depth_cache!
|
205
|
-
raise Error.new("Cannot rebuild depth cache for model without depth caching.") unless respond_to? :depth_cache_field
|
206
|
-
self.base_class.all.each do |node|
|
207
|
-
node.update_attribute depth_cache_field, node.depth
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|