ancestry 4.0.0 → 4.1.0
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 +4 -4
- data/CHANGELOG.md +10 -1
- data/README.md +12 -1
- data/lib/ancestry/instance_methods.rb +29 -8
- data/lib/ancestry/materialized_path.rb +1 -8
- data/lib/ancestry/materialized_path_pg.rb +1 -1
- data/lib/ancestry/version.rb +1 -1
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 236bf763182abf156d175085f58ec757d196523e4b6f388cfbd4830768194adb
|
4
|
+
data.tar.gz: b69ba3c642ee2ea03f46c62c23e7f45207d366f57ccfce2e77d0040fe3286a00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a29628a71c79f4d2889620833f91c25266bf491e0925edf8cdf38a74f0ee813f186ffc9dd1beb4d134ea0bcdb091a619f00fafcd557305a797468f4601cd75c
|
7
|
+
data.tar.gz: 9cbe99bad12c8b2a6a8a6f09b003d5ce17530e668f2dcf17be9502053606d26bf4f9b7ee7493a13a7b4d9fc44df8cd5d450477604fdbfa1aafbd2877193dc894
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,14 @@ a nice looking [Changelog](http://keepachangelog.com).
|
|
5
5
|
|
6
6
|
## Version [HEAD] <sub><sup>now</sub></sup>
|
7
7
|
|
8
|
+
## Version [4.1.0] <sub><sup>2021-06-25</sub></sup>
|
9
|
+
|
10
|
+
* `parent` with an invalid id now returns nil (thx @vanboom)
|
11
|
+
* `root` returns self if ancestry is invalid (thx @vanboom)
|
12
|
+
* fix case where invalid object prevented ancestry updates (thx @d-m-u)
|
13
|
+
* oracleenhanced uses nulls first for sorting (thx @lual)
|
14
|
+
* fix counter cache and STI (thx @mattvague)
|
15
|
+
|
8
16
|
## Version [4.0.0] <sub><sup>2021-04-12</sub></sup>
|
9
17
|
|
10
18
|
* dropped support for rails 4.2 and 5.0 (thx @d-m-u)
|
@@ -255,7 +263,8 @@ Missed 2 commits (which are feature adds)
|
|
255
263
|
* Validations
|
256
264
|
|
257
265
|
|
258
|
-
[HEAD]: https://github.com/stefankroes/ancestry/compare/v4.
|
266
|
+
[HEAD]: https://github.com/stefankroes/ancestry/compare/v4.1.0...HEAD
|
267
|
+
[4.1.0]: https://github.com/stefankroes/ancestry/compare/v4.0.0...v4.1.0
|
259
268
|
[4.0.0]: https://github.com/stefankroes/ancestry/compare/v3.2.1...v4.0.0
|
260
269
|
[3.2.1]: https://github.com/stefankroes/ancestry/compare/v3.2.0...v3.2.1
|
261
270
|
[3.2.0]: https://github.com/stefankroes/ancestry/compare/v3.1.0...v3.2.0
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[](https://gitter.im/stefankroes/ancestry?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://hakiri.io/github/stefankroes/ancestry/master)
|
2
2
|
|
3
3
|
# Ancestry
|
4
4
|
|
@@ -52,6 +52,17 @@ $ rails g migration add_ancestry_to_[table] ancestry:string:index
|
|
52
52
|
$ rake db:migrate
|
53
53
|
```
|
54
54
|
|
55
|
+
Depending upon your comfort with databases, you may want to create the column
|
56
|
+
with `C` or `POSIX` encoding. This is a more primitive encoding and just compares
|
57
|
+
bytes. Since this column will just contains numbers and slashes, it works much
|
58
|
+
better. It also works better for the uuid case as well.
|
59
|
+
|
60
|
+
|
61
|
+
If you opt out of this, and are trying to run tests on postgres, you may need to
|
62
|
+
set the environment variable `COLLATE_SYMBOLS=false`. Sorry to say that a discussion
|
63
|
+
on this topic is out of scope. The important take away is postgres sort order is
|
64
|
+
not consistent across operating systems but other databases do not have this same
|
65
|
+
issue.
|
55
66
|
|
56
67
|
## Add ancestry to your model
|
57
68
|
* Add to app/models/[model.rb]:
|
@@ -8,7 +8,7 @@ module Ancestry
|
|
8
8
|
# Update descendants with new ancestry (before save)
|
9
9
|
def update_descendants_with_new_ancestry
|
10
10
|
# If enabled and node is existing and ancestry was updated and the new ancestry is sane ...
|
11
|
-
if !ancestry_callbacks_disabled? && !new_record? && ancestry_changed? &&
|
11
|
+
if !ancestry_callbacks_disabled? && !new_record? && ancestry_changed? && sane_ancestor_ids?
|
12
12
|
# ... for each descendant ...
|
13
13
|
unscoped_descendants.each do |descendant|
|
14
14
|
# ... replace old ancestry with new ancestry
|
@@ -62,7 +62,7 @@ module Ancestry
|
|
62
62
|
|
63
63
|
# Counter Cache
|
64
64
|
def increase_parent_counter_cache
|
65
|
-
self.
|
65
|
+
self.ancestry_base_class.increment_counter _counter_cache_column, parent_id
|
66
66
|
end
|
67
67
|
|
68
68
|
def decrease_parent_counter_cache
|
@@ -74,7 +74,7 @@ module Ancestry
|
|
74
74
|
return if defined?(@_trigger_destroy_callback) && !@_trigger_destroy_callback
|
75
75
|
return if ancestry_callbacks_disabled?
|
76
76
|
|
77
|
-
self.
|
77
|
+
self.ancestry_base_class.decrement_counter _counter_cache_column, parent_id
|
78
78
|
end
|
79
79
|
|
80
80
|
def update_parent_counter_cache
|
@@ -83,10 +83,10 @@ module Ancestry
|
|
83
83
|
return unless changed
|
84
84
|
|
85
85
|
if parent_id_was = parent_id_before_last_save
|
86
|
-
self.
|
86
|
+
self.ancestry_base_class.decrement_counter _counter_cache_column, parent_id_was
|
87
87
|
end
|
88
88
|
|
89
|
-
parent_id && self.
|
89
|
+
parent_id && self.ancestry_base_class.increment_counter(_counter_cache_column, parent_id)
|
90
90
|
end
|
91
91
|
|
92
92
|
def _counter_cache_column
|
@@ -108,7 +108,20 @@ module Ancestry
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def sane_ancestor_ids?
|
111
|
-
|
111
|
+
current_context, self.validation_context = validation_context, nil
|
112
|
+
errors.clear
|
113
|
+
|
114
|
+
attribute = ancestry_base_class.ancestry_column
|
115
|
+
ancestry_value = send(attribute)
|
116
|
+
return true unless ancestry_value
|
117
|
+
|
118
|
+
self.class.validators_on(attribute).each do |validator|
|
119
|
+
validator.validate_each(self, attribute, ancestry_value)
|
120
|
+
end
|
121
|
+
ancestry_exclude_self
|
122
|
+
errors.none?
|
123
|
+
ensure
|
124
|
+
self.validation_context = current_context
|
112
125
|
end
|
113
126
|
|
114
127
|
def ancestors depth_options = {}
|
@@ -158,7 +171,11 @@ module Ancestry
|
|
158
171
|
alias :parent_id? :ancestors?
|
159
172
|
|
160
173
|
def parent
|
161
|
-
|
174
|
+
if has_parent?
|
175
|
+
unscoped_where do |scope|
|
176
|
+
scope.find_by id: parent_id
|
177
|
+
end
|
178
|
+
end
|
162
179
|
end
|
163
180
|
|
164
181
|
def parent_of?(node)
|
@@ -172,7 +189,11 @@ module Ancestry
|
|
172
189
|
end
|
173
190
|
|
174
191
|
def root
|
175
|
-
has_parent?
|
192
|
+
if has_parent?
|
193
|
+
unscoped_where { |scope| scope.find_by(id: root_id) } || self
|
194
|
+
else
|
195
|
+
self
|
196
|
+
end
|
176
197
|
end
|
177
198
|
|
178
199
|
def is_root?
|
@@ -67,7 +67,7 @@ module Ancestry
|
|
67
67
|
def ordered_by_ancestry(order = nil)
|
68
68
|
if %w(mysql mysql2 sqlite sqlite3).include?(connection.adapter_name.downcase)
|
69
69
|
reorder(arel_table[ancestry_column], order)
|
70
|
-
elsif %w(postgresql).include?(connection.adapter_name.downcase) && ActiveRecord::VERSION::STRING >= "6.1"
|
70
|
+
elsif %w(postgresql oracleenhanced).include?(connection.adapter_name.downcase) && ActiveRecord::VERSION::STRING >= "6.1"
|
71
71
|
reorder(Arel::Nodes::Ascending.new(arel_table[ancestry_column]).nulls_first, order)
|
72
72
|
else
|
73
73
|
reorder(
|
@@ -82,13 +82,6 @@ module Ancestry
|
|
82
82
|
end
|
83
83
|
|
84
84
|
module InstanceMethods
|
85
|
-
|
86
|
-
# Validates the ancestry, but can also be applied if validation is bypassed to determine if children should be affected
|
87
|
-
def sane_ancestry?
|
88
|
-
ancestry_value = read_attribute(self.ancestry_base_class.ancestry_column)
|
89
|
-
(ancestry_value.nil? || !ancestor_ids.include?(self.id)) && valid?
|
90
|
-
end
|
91
|
-
|
92
85
|
# optimization - better to go directly to column and avoid parsing
|
93
86
|
def ancestors?
|
94
87
|
read_attribute(self.ancestry_base_class.ancestry_column).present?
|
@@ -3,7 +3,7 @@ module Ancestry
|
|
3
3
|
# Update descendants with new ancestry (before save)
|
4
4
|
def update_descendants_with_new_ancestry
|
5
5
|
# If enabled and node is existing and ancestry was updated and the new ancestry is sane ...
|
6
|
-
if !ancestry_callbacks_disabled? && !new_record? && ancestry_changed? &&
|
6
|
+
if !ancestry_callbacks_disabled? && !new_record? && ancestry_changed? && sane_ancestor_ids?
|
7
7
|
ancestry_column = ancestry_base_class.ancestry_column
|
8
8
|
old_ancestry = path_ids_in_database.join(Ancestry::MaterializedPath::ANCESTRY_DELIMITER)
|
9
9
|
new_ancestry = path_ids.join(Ancestry::MaterializedPath::ANCESTRY_DELIMITER)
|
data/lib/ancestry/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ancestry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Kroes
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-06-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 5.2.
|
20
|
+
version: 5.2.6
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 5.2.
|
27
|
+
version: 5.2.6
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: appraisal
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,6 +67,20 @@ dependencies:
|
|
67
67
|
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '13.0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: simplecov
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
70
84
|
- !ruby/object:Gem::Dependency
|
71
85
|
name: yard
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,14 +137,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
137
|
requirements:
|
124
138
|
- - ">="
|
125
139
|
- !ruby/object:Gem::Version
|
126
|
-
version: 2.
|
140
|
+
version: '2.5'
|
127
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
143
|
- - ">="
|
130
144
|
- !ruby/object:Gem::Version
|
131
145
|
version: '0'
|
132
146
|
requirements: []
|
133
|
-
rubygems_version: 3.
|
147
|
+
rubygems_version: 3.2.16
|
134
148
|
signing_key:
|
135
149
|
specification_version: 4
|
136
150
|
summary: Organize ActiveRecord model into a tree structure
|