ancestry 4.3.0 → 4.3.2
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 +27 -1
- data/lib/ancestry/has_ancestry.rb +1 -6
- data/lib/ancestry/instance_methods.rb +8 -8
- data/lib/ancestry/materialized_path.rb +8 -0
- data/lib/ancestry/version.rb +1 -1
- metadata +3 -6
- data/lib/ancestry/array_pattern_validator.rb +0 -27
- data/lib/ancestry/materialized_path_string.rb +0 -46
- data/lib/ancestry/materialized_path_string2.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c49a8b31bcfbc287a47c4b03ceed6902efc763ef2b120b89fbd18aa9ac93a30e
|
4
|
+
data.tar.gz: f1cf8e4f308fb7ec6b18526a4c86e715416e841fd91f010205b6bdfdd4e3accb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d8d4702482f4d9a3183d991031b9fdb870ad2ff6de7eac8a8a3fac7dd8bb68d7b34bef6add6f22ec5ef51d430194082cce6d8a15d63b8f059feb2ecc7ef4875
|
7
|
+
data.tar.gz: '09e1135d7334ff5181df9574c4554ea0a28c4b350b50049d56e16cb0cec07a7b3e60a7ebc33d119dd6704211d152d293627a7c7372a604ce05167e877515164e'
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,17 @@
|
|
3
3
|
Doing our best at supporting [SemVer](http://semver.org/) with
|
4
4
|
a nice looking [Changelog](http://keepachangelog.com).
|
5
5
|
|
6
|
+
## Version [4.3.2] <sub><sup>2023-03-25</sub></sup>
|
7
|
+
|
8
|
+
* Fix: added back fields that were removed in #589 [#647](https://github.com/stefankroes/ancestry/pull/647) (thx @rastamhadi)
|
9
|
+
- path_ids_in_database
|
10
|
+
|
11
|
+
## Version [4.3.1] <sub><sup>2023-03-19</sub></sup>
|
12
|
+
|
13
|
+
* Fix: added back fields that were removed in #589 [#637](https://github.com/stefankroes/ancestry/pull/637) (thx @znz)
|
14
|
+
- ancestor_ids_in_database
|
15
|
+
- parent_id_in_database
|
16
|
+
|
6
17
|
## Version [4.3.0] <sub><sup>2023-03-09</sub></sup>
|
7
18
|
|
8
19
|
* Fix: materialized_path2 strategy [#597](https://github.com/stefankroes/ancestry/pull/597) (thx @kshnurov)
|
@@ -13,7 +24,22 @@ a nice looking [Changelog](http://keepachangelog.com).
|
|
13
24
|
* Documented column collation and testing [#601](https://github.com/stefankroes/ancestry/pull/601) [#607](https://github.com/stefankroes/ancestry/pull/607) (thx @kshnurov)
|
14
25
|
* Added initializer with default_ancestry_format [#612](https://github.com/stefankroes/ancestry/pull/612) [#613](https://github.com/stefankroes/ancestry/pull/613)
|
15
26
|
* ruby 3.2 support [#596](https://github.com/stefankroes/ancestry/pull/596) (thx @petergoldstein)
|
16
|
-
*
|
27
|
+
* Reduce memory for sort_by_ancestry [#415](https://github.com/stefankroes/ancestry/pull/415)
|
28
|
+
|
29
|
+
#### Notable features
|
30
|
+
|
31
|
+
Default configuration values are provided for a few options: `update_strategy`, `ancestry_format`, and `primary_key_format`.
|
32
|
+
These can be set in an initializer via `Ancestry.default_{ancestry_format} = value`
|
33
|
+
|
34
|
+
A new `ancestry_format` of `:materialized_path2` formats the ancestry column with leading and trailing slashes.
|
35
|
+
It shows promise to make the `ancestry` field more sql friendly.
|
36
|
+
|
37
|
+
Both of these are better documented in [the readme](/README.md).
|
38
|
+
|
39
|
+
#### Breaking changes
|
40
|
+
|
41
|
+
- `ancestry_primary_key_format` is now specified or a single key not the whole regular expression.
|
42
|
+
We used to accept `/\A[0-9]+(/[0-9]+)*` or `'[0-9]'`, but now we only accept `'[0-9]'`.
|
17
43
|
|
18
44
|
## Version [4.2.0] <sub><sup>2022-06-09</sub></sup>
|
19
45
|
|
@@ -83,12 +83,7 @@ module Ancestry
|
|
83
83
|
# Create counter cache column accessor and set to option or default
|
84
84
|
if options[:counter_cache]
|
85
85
|
cattr_accessor :counter_cache_column
|
86
|
-
|
87
|
-
if options[:counter_cache] == true
|
88
|
-
self.counter_cache_column = :children_count
|
89
|
-
else
|
90
|
-
self.counter_cache_column = options[:counter_cache]
|
91
|
-
end
|
86
|
+
self.counter_cache_column = options[:counter_cache] == true ? 'children_count' : options[:counter_cache].to_s
|
92
87
|
|
93
88
|
after_create :increase_parent_counter_cache, if: :has_parent?
|
94
89
|
after_destroy :decrease_parent_counter_cache, if: :has_parent?
|
@@ -62,7 +62,7 @@ module Ancestry
|
|
62
62
|
|
63
63
|
# Counter Cache
|
64
64
|
def increase_parent_counter_cache
|
65
|
-
self.ancestry_base_class.increment_counter
|
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.ancestry_base_class.decrement_counter
|
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,14 +83,10 @@ module Ancestry
|
|
83
83
|
return unless changed
|
84
84
|
|
85
85
|
if parent_id_was = parent_id_before_last_save
|
86
|
-
self.ancestry_base_class.decrement_counter
|
86
|
+
self.ancestry_base_class.decrement_counter counter_cache_column, parent_id_was
|
87
87
|
end
|
88
88
|
|
89
|
-
parent_id &&
|
90
|
-
end
|
91
|
-
|
92
|
-
def _counter_cache_column
|
93
|
-
self.ancestry_base_class.counter_cache_column.to_s
|
89
|
+
parent_id && increase_parent_counter_cache
|
94
90
|
end
|
95
91
|
|
96
92
|
# Ancestors
|
@@ -137,6 +133,10 @@ module Ancestry
|
|
137
133
|
ancestor_ids_before_last_save + [id]
|
138
134
|
end
|
139
135
|
|
136
|
+
def path_ids_in_database
|
137
|
+
ancestor_ids_in_database + [id]
|
138
|
+
end
|
139
|
+
|
140
140
|
def path depth_options = {}
|
141
141
|
self.ancestry_base_class.scope_depth(depth_options, depth).ordered_by_ancestry.inpath_of(self)
|
142
142
|
end
|
@@ -124,10 +124,18 @@ module Ancestry
|
|
124
124
|
parse_ancestry_column(read_attribute(self.ancestry_base_class.ancestry_column))
|
125
125
|
end
|
126
126
|
|
127
|
+
def ancestor_ids_in_database
|
128
|
+
parse_ancestry_column(attribute_in_database(self.class.ancestry_column))
|
129
|
+
end
|
130
|
+
|
127
131
|
def ancestor_ids_before_last_save
|
128
132
|
parse_ancestry_column(attribute_before_last_save(self.ancestry_base_class.ancestry_column))
|
129
133
|
end
|
130
134
|
|
135
|
+
def parent_id_in_database
|
136
|
+
parse_ancestry_column(attribute_in_database(self.class.ancestry_column)).last
|
137
|
+
end
|
138
|
+
|
131
139
|
def parent_id_before_last_save
|
132
140
|
parse_ancestry_column(attribute_before_last_save(self.ancestry_base_class.ancestry_column)).last
|
133
141
|
end
|
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.3.
|
4
|
+
version: 4.3.2
|
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: 2023-03-
|
12
|
+
date: 2023-03-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -112,7 +112,6 @@ files:
|
|
112
112
|
- MIT-LICENSE
|
113
113
|
- README.md
|
114
114
|
- lib/ancestry.rb
|
115
|
-
- lib/ancestry/array_pattern_validator.rb
|
116
115
|
- lib/ancestry/class_methods.rb
|
117
116
|
- lib/ancestry/exceptions.rb
|
118
117
|
- lib/ancestry/has_ancestry.rb
|
@@ -121,8 +120,6 @@ files:
|
|
121
120
|
- lib/ancestry/materialized_path.rb
|
122
121
|
- lib/ancestry/materialized_path2.rb
|
123
122
|
- lib/ancestry/materialized_path_pg.rb
|
124
|
-
- lib/ancestry/materialized_path_string.rb
|
125
|
-
- lib/ancestry/materialized_path_string2.rb
|
126
123
|
- lib/ancestry/version.rb
|
127
124
|
homepage: https://github.com/stefankroes/ancestry
|
128
125
|
licenses:
|
@@ -148,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
145
|
- !ruby/object:Gem::Version
|
149
146
|
version: '0'
|
150
147
|
requirements: []
|
151
|
-
rubygems_version: 3.
|
148
|
+
rubygems_version: 3.2.32
|
152
149
|
signing_key:
|
153
150
|
specification_version: 4
|
154
151
|
summary: Organize ActiveRecord model into a tree structure
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Ancestry
|
2
|
-
class ArrayPatternValidator < ActiveModel::EachValidator
|
3
|
-
def initialize(options)
|
4
|
-
raise ArgumentError, "Pattern unspecified, Specify using :pattern" unless options[:pattern]
|
5
|
-
|
6
|
-
options[:pattern] = /\A#{options[:pattern].to_s}\Z/ unless options[:pattern].to_s.include?('\A')
|
7
|
-
options[:id] = true unless options.key?(:id)
|
8
|
-
options[:integer] = true unless options.key?(:integer)
|
9
|
-
|
10
|
-
super
|
11
|
-
end
|
12
|
-
|
13
|
-
def validate_each(record, attribute, value)
|
14
|
-
if options[:id] && value.include?(record.id)
|
15
|
-
record.errors.add(attribute, I18n.t("ancestry.exclude_self", {:class_name => self.class.name.humanize}))
|
16
|
-
end
|
17
|
-
|
18
|
-
if value.any? { |v| v.to_s !~ options[:pattern] }
|
19
|
-
record.errors.add(attribute, "illegal characters")
|
20
|
-
end
|
21
|
-
|
22
|
-
if options[:integer] && value.any? { |v| v < 1 }
|
23
|
-
record.errors.add(attribute, "non positive ancestor id")
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
module Ancestry
|
2
|
-
class MaterializedPathString < ActiveRecord::Type::Value
|
3
|
-
def initialize(casting: :to_i, delimiter: '/')
|
4
|
-
@casting = casting&.to_proc
|
5
|
-
@delimiter = delimiter
|
6
|
-
end
|
7
|
-
|
8
|
-
def type
|
9
|
-
:materialized_path_string
|
10
|
-
end
|
11
|
-
|
12
|
-
# convert to database type
|
13
|
-
def serialize(value)
|
14
|
-
if value.kind_of?(Array)
|
15
|
-
value.map(&:to_s).join(@delimiter).presence
|
16
|
-
elsif value.kind_of?(Integer)
|
17
|
-
value.to_s
|
18
|
-
elsif value.nil? || value.kind_of?(String)
|
19
|
-
value
|
20
|
-
else
|
21
|
-
byebug
|
22
|
-
puts "curious type: #{value.class}"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def cast(value)
|
27
|
-
cast_value(value) #unless value.nil? (want to get rid of this - fix default value)
|
28
|
-
end
|
29
|
-
|
30
|
-
# called by cast (form or setter) or deserialize (database)
|
31
|
-
def cast_value(value)
|
32
|
-
if value.kind_of?(Array)
|
33
|
-
super
|
34
|
-
elsif value.nil?
|
35
|
-
# would prefer to use default here
|
36
|
-
# but with default, it kept thinking the field had changed when it hadn't
|
37
|
-
# (that may be a rails bug though)
|
38
|
-
super([])
|
39
|
-
else
|
40
|
-
#TODO: test ancestry=1
|
41
|
-
super(value.to_s.split(@delimiter).map(&@casting))
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
ActiveRecord::Type.register(:materialized_path_string, Ancestry::MaterializedPathString)
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# used for materialized path
|
2
|
-
class MaterializedPathString2 < ActiveRecord::Type::Value
|
3
|
-
def initialize(casting: :to_i, delimiter: '/')
|
4
|
-
@casting = casting&.to_proc
|
5
|
-
@delimiter = delimiter
|
6
|
-
end
|
7
|
-
|
8
|
-
def type
|
9
|
-
:materialized_path_string2
|
10
|
-
end
|
11
|
-
|
12
|
-
# convert to database type
|
13
|
-
def serialize(value)
|
14
|
-
if value.kind_of?(Array)
|
15
|
-
# TODO: check all values to ensure no extra slashes
|
16
|
-
value.empty? ? @delimiter : "#{@delimiter}#{value.map(&:to_s).join(@delimiter)}#{@delimiter}"
|
17
|
-
elsif value.kind_of?(Integer)
|
18
|
-
value.to_s
|
19
|
-
elsif value.nil? || value.kind_of?(String)
|
20
|
-
value
|
21
|
-
else
|
22
|
-
byebug
|
23
|
-
puts "curious type: #{value.class}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def cast(value)
|
28
|
-
cast_value(value) #unless value.nil? (want to get rid of this - fix default value)
|
29
|
-
end
|
30
|
-
|
31
|
-
# called by cast (form or setter) or deserialize (database)
|
32
|
-
def cast_value(value)
|
33
|
-
if value.kind_of?(Array)
|
34
|
-
super
|
35
|
-
elsif value.nil?
|
36
|
-
# would prefer to use default here
|
37
|
-
# but with default, it kept thinking the field had changed when it hadn't
|
38
|
-
super([])
|
39
|
-
else
|
40
|
-
#TODO: test ancestry=1
|
41
|
-
super(value.to_s.split(@delimiter).map(&@casting))
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
ActiveRecord::Type.register(:materialized_path_string2, Ancestry::MaterializedPathString)
|