awesome_nested_set 3.0.3 → 3.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 +4 -1
- data/README.md +5 -3
- data/lib/awesome_nested_set/columns.rb +4 -0
- data/lib/awesome_nested_set/model.rb +17 -3
- data/lib/awesome_nested_set/model/movable.rb +2 -1
- data/lib/awesome_nested_set/model/prunable.rb +1 -1
- data/lib/awesome_nested_set/model/transactable.rb +1 -1
- data/lib/awesome_nested_set/model/validatable.rb +13 -2
- data/lib/awesome_nested_set/tree.rb +11 -1
- data/lib/awesome_nested_set/version.rb +1 -1
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ddb25974895907e5a9dd2e701894678e7f14f338
|
4
|
+
data.tar.gz: 806590f9ab37cbc3756f15e613b4ae6226cab542
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2e80c6b55ce284b9e151a1a4ba02246284cd1718e3aea16f3a5cb5419cfb4743c826537ceb0a0f0ae2f735eaa177f991b1b0035de6acb99e4357acedca74584
|
7
|
+
data.tar.gz: 08bc67738a4b4401aa49bcb9ef6098b0361e10d3bb2b4e916dd69f58020c7a994a7c0db6cb428bcf1fbfbefd567690c45f8b89b17ed83d953f4d800125c770c1
|
data/CHANGELOG
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
3.0
|
1
|
+
3.1.0
|
2
|
+
* Ensure that nested_set queries respect the model's default_scope. [oesgalha](https://github.com/oesgalha)
|
3
|
+
* Add Rails 5 support [Krzysztof Rybka](https://github.com/krzysiek1507)
|
4
|
+
* Fix .all_roots_valid? method when model is ordered by default [Adam Hodowany](https://github.com/hodak)
|
2
5
|
* Reuse the current model's connection when available [Tim Bugai] [#322](https://github.com/collectiveidea/awesome_nested_set/pull/322)
|
3
6
|
|
4
7
|
3.0.3
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
Awesome Nested Set is an implementation of the nested set pattern for ActiveRecord models.
|
7
7
|
It is a replacement for acts_as_nested_set and BetterNestedSet, but more awesome.
|
8
8
|
|
9
|
-
Version 3 supports Rails 4. Version 2 supports Rails 3. Gem versions prior to 2.0 support Rails 2.
|
9
|
+
Version 3.1 supports Rails 5 & 4. Version 2 supports Rails 3. Gem versions prior to 2.0 support Rails 2.
|
10
10
|
|
11
11
|
## What makes this so awesome?
|
12
12
|
|
@@ -26,6 +26,8 @@ gem 'awesome_nested_set'
|
|
26
26
|
To make use of `awesome_nested_set` your model needs to have 3 fields:
|
27
27
|
`lft`, `rgt`, and `parent_id`. The names of these fields are configurable.
|
28
28
|
You can also have optional fields: `depth` and `children_count`. These fields are configurable.
|
29
|
+
Note that the `childrent_count` column must have `null: false` and `default: 0` to
|
30
|
+
function properly.
|
29
31
|
|
30
32
|
```ruby
|
31
33
|
class CreateCategories < ActiveRecord::Migration
|
@@ -66,7 +68,7 @@ You can pass various options to `acts_as_nested_set` macro. Configuration option
|
|
66
68
|
* `left_column`: column name for left boundary data (default: lft)
|
67
69
|
* `right_column`: column name for right boundary data (default: rgt)
|
68
70
|
* `depth_column`: column name for the depth data default (default: depth)
|
69
|
-
* `scope`: restricts what is to be considered a list. Given a symbol, it'll attach
|
71
|
+
* `scope`: restricts what is to be considered a list. Given a symbol, it'll attach `_id` (if it hasn't been already) and use that as the foreign key restriction. You can also pass an array to scope by multiple attributes. Example: `acts_as_nested_set :scope => [:notable_id, :notable_type]`
|
70
72
|
* `dependent`: behavior for cascading destroy. If set to :destroy, all the child objects are destroyed alongside this object by calling their destroy method. If set to :delete_all (default), all the child objects are deleted without calling their destroy method. If set to :nullify, all child objects will become orphaned and become roots themselves.
|
71
73
|
* `counter_cache`: adds a counter cache for the number of children. defaults to false. Example: `acts_as_nested_set :counter_cache => :children_count`
|
72
74
|
* `order_column`: on which column to do sorting, by default it is the left_column_name. Example: `acts_as_nested_set :order_column => :position`
|
@@ -237,4 +239,4 @@ You can learn more about nested sets at: http://threebit.net/tutorials/nestedset
|
|
237
239
|
|
238
240
|
Please see the ['Contributing' document](CONTRIBUTING.md).
|
239
241
|
|
240
|
-
Copyright © 2008
|
242
|
+
Copyright © 2008–2015 [Collective Idea](http://collectiveidea.com), released under the MIT license.
|
@@ -31,6 +31,10 @@ module CollectiveIdea #:nodoc:
|
|
31
31
|
Array(acts_as_nested_set_options[:scope])
|
32
32
|
end
|
33
33
|
|
34
|
+
def counter_cache_column_name
|
35
|
+
acts_as_nested_set_options[:counter_cache]
|
36
|
+
end
|
37
|
+
|
34
38
|
def quoted_left_column_name
|
35
39
|
model_connection.quote_column_name(left_column_name)
|
36
40
|
end
|
@@ -145,7 +145,7 @@ module CollectiveIdea #:nodoc:
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
148
|
-
self.class.base_class.
|
148
|
+
self.class.base_class.nested_set_scope options
|
149
149
|
end
|
150
150
|
|
151
151
|
# Separate an other `nested_set_scope` for unscoped model
|
@@ -154,7 +154,7 @@ module CollectiveIdea #:nodoc:
|
|
154
154
|
# And class level `nested_set_scope` seems just for query `root` `child` .. etc
|
155
155
|
# I think we don't have to provide unscoped `nested_set_scope` in class level.
|
156
156
|
def nested_set_scope_without_default_scope(*args)
|
157
|
-
self.class.unscoped do
|
157
|
+
self.class.base_class.unscoped do
|
158
158
|
nested_set_scope(*args)
|
159
159
|
end
|
160
160
|
end
|
@@ -182,7 +182,7 @@ module CollectiveIdea #:nodoc:
|
|
182
182
|
end
|
183
183
|
|
184
184
|
def right_most_node
|
185
|
-
@right_most_node ||=
|
185
|
+
@right_most_node ||= nested_set_scope_without_default_scope(
|
186
186
|
:order => "#{quoted_right_column_full_name} desc"
|
187
187
|
).first
|
188
188
|
end
|
@@ -232,6 +232,20 @@ module CollectiveIdea #:nodoc:
|
|
232
232
|
end
|
233
233
|
end
|
234
234
|
|
235
|
+
def update_counter_cache
|
236
|
+
return unless acts_as_nested_set_options[:counter_cache]
|
237
|
+
|
238
|
+
# Decrease the counter for all old parents
|
239
|
+
if old_parent = self.parent
|
240
|
+
self.class.decrement_counter(acts_as_nested_set_options[:counter_cache], old_parent)
|
241
|
+
end
|
242
|
+
|
243
|
+
# Increase the counter for all new parents
|
244
|
+
if new_parent = self.reload.parent
|
245
|
+
self.class.increment_counter(acts_as_nested_set_options[:counter_cache], new_parent)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
235
249
|
def set_default_left_and_right
|
236
250
|
# adds the new node to the right of all existing nodes
|
237
251
|
self[left_column_name] = right_most_bound + 1
|
@@ -46,7 +46,7 @@ module CollectiveIdea #:nodoc:
|
|
46
46
|
elsif node.children.count == index
|
47
47
|
move_to_right_of(node.children.last)
|
48
48
|
else
|
49
|
-
my_position = node.children.index(self)
|
49
|
+
my_position = node.children.to_a.index(self)
|
50
50
|
if my_position && my_position < index
|
51
51
|
# e.g. if self is at position 0 and we want to move self to position 1 then self
|
52
52
|
# needs to move to the *right* of the node at position 1. That's because the node
|
@@ -105,6 +105,7 @@ module CollectiveIdea #:nodoc:
|
|
105
105
|
self.reload_nested_set
|
106
106
|
|
107
107
|
Move.new(target, position, self).move
|
108
|
+
update_counter_cache
|
108
109
|
end
|
109
110
|
after_move_to(target, position)
|
110
111
|
end
|
@@ -47,7 +47,7 @@ module CollectiveIdea #:nodoc:
|
|
47
47
|
elsif acts_as_nested_set_options[:dependent] == :restrict_with_error
|
48
48
|
unless leaf?
|
49
49
|
record = self.class.human_attribute_name(:children).downcase
|
50
|
-
errors.add(:base, :"restrict_dependent_destroy
|
50
|
+
errors.add(:base, :"restrict_dependent_destroy.#{Rails::VERSION::MAJOR < 5 ? 'many' : 'has_many'}", record: record)
|
51
51
|
return false
|
52
52
|
end
|
53
53
|
return true
|
@@ -17,7 +17,7 @@ module CollectiveIdea #:nodoc:
|
|
17
17
|
rescue CollectiveIdea::Acts::NestedSet::Move::ImpossibleMove
|
18
18
|
raise
|
19
19
|
rescue ActiveRecord::StatementInvalid => error
|
20
|
-
raise OpenTransactionsIsNotZero.new(error.message) unless connection.open_transactions.zero?
|
20
|
+
raise OpenTransactionsIsNotZero.new(error.message) unless self.class.connection.open_transactions.zero?
|
21
21
|
raise unless error.message =~ /[Dd]eadlock|Lock wait timeout exceeded/
|
22
22
|
raise DeadlockDetected.new(error.message) unless retry_count < 10
|
23
23
|
retry_count += 1
|
@@ -41,8 +41,10 @@ module CollectiveIdea
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def each_root_valid?(roots_to_validate)
|
44
|
+
left_column = acts_as_nested_set_options[:left_column]
|
45
|
+
reordered_roots = roots_reordered_by_column(roots_to_validate, left_column)
|
44
46
|
left = right = 0
|
45
|
-
|
47
|
+
reordered_roots.all? do |root|
|
46
48
|
(root.left > left && root.right > right).tap do
|
47
49
|
left = root.left
|
48
50
|
right = root.right
|
@@ -57,12 +59,21 @@ module CollectiveIdea
|
|
57
59
|
}
|
58
60
|
end
|
59
61
|
|
62
|
+
def roots_reordered_by_column(roots_to_reorder, column)
|
63
|
+
if roots_to_reorder.respond_to?(:reorder) # ActiveRecord's relation
|
64
|
+
roots_to_reorder.reorder(column)
|
65
|
+
elsif roots_to_reorder.respond_to?(:sort) # Array
|
66
|
+
roots_to_reorder.sort { |a, b| a.send(column) <=> b.send(column) }
|
67
|
+
else
|
68
|
+
roots_to_reorder
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
60
72
|
def scope_string
|
61
73
|
Array(acts_as_nested_set_options[:scope]).map do |c|
|
62
74
|
connection.quote_column_name(c)
|
63
75
|
end.push(nil).join(", ")
|
64
76
|
end
|
65
|
-
|
66
77
|
end
|
67
78
|
end
|
68
79
|
end
|
@@ -6,7 +6,7 @@ module CollectiveIdea #:nodoc:
|
|
6
6
|
attr_accessor :indices
|
7
7
|
|
8
8
|
delegate :left_column_name, :right_column_name, :quoted_parent_column_full_name,
|
9
|
-
:order_for_rebuild, :scope_for_rebuild,
|
9
|
+
:order_for_rebuild, :scope_for_rebuild, :counter_cache_column_name,
|
10
10
|
:to => :model
|
11
11
|
|
12
12
|
def initialize(model, validate_nodes)
|
@@ -23,6 +23,7 @@ module CollectiveIdea #:nodoc:
|
|
23
23
|
# setup index for this scope
|
24
24
|
indices[scope_for_rebuild.call(root_node)] ||= 0
|
25
25
|
set_left_and_rights(root_node)
|
26
|
+
reset_counter_cache(root_node)
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
@@ -57,6 +58,15 @@ module CollectiveIdea #:nodoc:
|
|
57
58
|
def set_right!(node)
|
58
59
|
node[right_column_name] = increment_indice!(node)
|
59
60
|
end
|
61
|
+
|
62
|
+
def reset_counter_cache(node)
|
63
|
+
return unless counter_cache_column_name
|
64
|
+
node.class.reset_counters(node.id, :children)
|
65
|
+
|
66
|
+
node.children.each do |child|
|
67
|
+
reset_counter_cache(child)
|
68
|
+
end
|
69
|
+
end
|
60
70
|
end
|
61
71
|
end
|
62
72
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: awesome_nested_set
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Keepers
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-05-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 4.0.0
|
22
22
|
- - "<"
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: '5'
|
24
|
+
version: '5.1'
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -31,21 +31,21 @@ dependencies:
|
|
31
31
|
version: 4.0.0
|
32
32
|
- - "<"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '5'
|
34
|
+
version: '5.1'
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: rspec-rails
|
37
37
|
requirement: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - '='
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
41
|
+
version: 3.5.0.beta3
|
42
42
|
type: :development
|
43
43
|
prerelease: false
|
44
44
|
version_requirements: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- -
|
46
|
+
- - '='
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
48
|
+
version: 3.5.0.beta3
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: rake
|
51
51
|
requirement: !ruby/object:Gem::Requirement
|
@@ -130,7 +130,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
130
|
requirements:
|
131
131
|
- - ">="
|
132
132
|
- !ruby/object:Gem::Version
|
133
|
-
version:
|
133
|
+
version: 2.0.0
|
134
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - ">="
|
@@ -138,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
138
|
version: '0'
|
139
139
|
requirements: []
|
140
140
|
rubyforge_project:
|
141
|
-
rubygems_version: 2.
|
141
|
+
rubygems_version: 2.6.2
|
142
142
|
signing_key:
|
143
143
|
specification_version: 4
|
144
144
|
summary: An awesome nested set implementation for Active Record
|