awesome_nested_set 3.0.3 → 3.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5ab643ea1dfe98a3df89d5bf2c142fd22d8d96f
4
- data.tar.gz: 3f6089e375d849c9cb600eb4c776c40323b3e67e
3
+ metadata.gz: 158eb30c327a8fa16c990178bf3a8b27b92df7f3
4
+ data.tar.gz: 6dc79c6c67d4d4a87615d1627a066aef746612e2
5
5
  SHA512:
6
- metadata.gz: 3afe6283157bd9937196de7ffe4239dac7be930417b505b306c92685cfdd703d9cf7463317994bc822490f4a426c0c88f3f3425501036cd00b00025a6f81dc8c
7
- data.tar.gz: d96cf10ce68aa34ccee951f3b04beec6eebd960748c42502ba48016b3f559cf798c657b2b9b36d4238c38d1ba0dbca08f53dab5f39f3d3bb37044dcb4dafe902
6
+ metadata.gz: c6816a36e5be6882f655779572f8174fce473e82c8b2b47a23402c72522132a061a8b3a29ad3f2d980b82b87f2536c69042ab1aa130a81f3618138ec2b2ea7ce
7
+ data.tar.gz: 35c3cf5f2cb9583c7d7c605a2209d5f3a8e4ed6538f914ee55da323f4d9f9eadb27494dfc6b77e67788d4eba49ab0aa0e7741731bb9341a83e43b759a233c817
data/CHANGELOG CHANGED
@@ -1,4 +1,17 @@
1
- 3.0.4
1
+ 3.1.3
2
+ * Add Rails 5.1 support [John Hawthorn](https://github.com/jhawthorn)
3
+
4
+ 3.1.2
5
+ * Make belongs_to relation optional again [Jan Matusz](https://marahin.pl/)
6
+
7
+ 3.1.1
8
+ * Fix a reloading bug when using default scope [Krzysztof Rybka](https://github.com/krzysiek1507)
9
+
10
+ 3.1.0
11
+ * Ensure that nested_set queries respect the model's default_scope. [oesgalha](https://github.com/oesgalha)
12
+ * Add Rails 5 support [Krzysztof Rybka](https://github.com/krzysiek1507)
13
+ * Drop support for ruby 1.9.3 [Krzysztof Rybka](https://github.com/krzysiek1507)
14
+ * Fix .all_roots_valid? method when model is ordered by default [Adam Hodowany](https://github.com/hodak)
2
15
  * Reuse the current model's connection when available [Tim Bugai] [#322](https://github.com/collectiveidea/awesome_nested_set/pull/322)
3
16
 
4
17
  3.0.3
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # Awesome Nested Set
2
2
 
3
- [![Build Status](https://travis-ci.org/collectiveidea/awesome_nested_set.png?branch=master)](https://travis-ci.org/collectiveidea/awesome_nested_set) [![Code Climate](https://codeclimate.com/github/collectiveidea/awesome_nested_set.png)](https://codeclimate.com/github/collectiveidea/awesome_nested_set) [![Dependency Status](https://gemnasium.com/collectiveidea/awesome_nested_set.svg)](https://gemnasium.com/collectiveidea/awesome_nested_set)
3
+ [![Build Status](https://travis-ci.org/collectiveidea/awesome_nested_set.svg?branch=master)](https://travis-ci.org/collectiveidea/awesome_nested_set) [![Code Climate](https://codeclimate.com/github/collectiveidea/awesome_nested_set.svg)](https://codeclimate.com/github/collectiveidea/awesome_nested_set) [![Dependency Status](https://gemnasium.com/collectiveidea/awesome_nested_set.svg)](https://gemnasium.com/collectiveidea/awesome_nested_set) [![Security](https://hakiri.io/github/collectiveidea/awesome_nested_set/master.svg)](https://hakiri.io/github/collectiveidea/awesome_nested_set/master)
4
4
 
5
5
 
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 `children_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 _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]`
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`
@@ -133,7 +135,7 @@ class Category < ActiveRecord::Base
133
135
  end
134
136
  ```
135
137
 
136
- ## Protecting attributes from mass assignment
138
+ ## Protecting attributes from mass assignment (for Rails < 4)
137
139
 
138
140
  It's generally best to "whitelist" the attributes that can be used in mass assignment:
139
141
 
@@ -229,12 +231,8 @@ Example usage:
229
231
 
230
232
  See [CollectiveIdea::Acts::NestedSet::Helper](lib/awesome_nested_set/helper.rb) for more information about the helpers.
231
233
 
232
- ## References
233
-
234
- You can learn more about nested sets at: http://threebit.net/tutorials/nestedset/tutorial1.html
235
-
236
234
  ## How to contribute
237
235
 
238
236
  Please see the ['Contributing' document](CONTRIBUTING.md).
239
237
 
240
- Copyright © 2008 - 2014 Collective Idea, released under the MIT license
238
+ Copyright © 2008–2015 [Collective Idea](http://collectiveidea.com), released under the MIT license.
@@ -1,8 +1,11 @@
1
+ require 'active_support/lazy_load_hooks'
1
2
  require 'awesome_nested_set/awesome_nested_set'
2
- require 'active_record'
3
- ActiveRecord::Base.send :extend, CollectiveIdea::Acts::NestedSet
4
3
 
5
- if defined?(ActionView)
4
+ ActiveSupport.on_load(:active_record) do
5
+ ActiveRecord::Base.send :extend, CollectiveIdea::Acts::NestedSet
6
+ end
7
+
8
+ ActiveSupport.on_load(:action_view) do
6
9
  require 'awesome_nested_set/helper'
7
10
  ActionView::Base.send :include, CollectiveIdea::Acts::NestedSet::Helper
8
11
  end
@@ -92,13 +92,17 @@ module CollectiveIdea #:nodoc:
92
92
  end
93
93
 
94
94
  def acts_as_nested_set_relate_parent!
95
- belongs_to :parent, :class_name => self.base_class.to_s,
96
- :foreign_key => parent_column_name,
97
- :primary_key => primary_column_name,
98
- :counter_cache => acts_as_nested_set_options[:counter_cache],
99
- :inverse_of => (:children unless acts_as_nested_set_options[:polymorphic]),
100
- :polymorphic => acts_as_nested_set_options[:polymorphic],
101
- :touch => acts_as_nested_set_options[:touch]
95
+ options = {
96
+ :class_name => self.base_class.to_s,
97
+ :foreign_key => parent_column_name,
98
+ :primary_key => primary_column_name,
99
+ :counter_cache => acts_as_nested_set_options[:counter_cache],
100
+ :inverse_of => (:children unless acts_as_nested_set_options[:polymorphic]),
101
+ :polymorphic => acts_as_nested_set_options[:polymorphic],
102
+ :touch => acts_as_nested_set_options[:touch]
103
+ }
104
+ options[:optional] = true if ActiveRecord::VERSION::MAJOR >= 5
105
+ belongs_to :parent, options
102
106
  end
103
107
 
104
108
  def acts_as_nested_set_default_options
@@ -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.unscoped.nested_set_scope options
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 ||= nested_set_scope(
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
@@ -250,7 +264,7 @@ module CollectiveIdea #:nodoc:
250
264
  if target.is_a? self.class.base_class
251
265
  target.reload
252
266
  elsif position != :root
253
- nested_set_scope.where(primary_column_name => target).first!
267
+ nested_set_scope_without_default_scope.where(primary_column_name => target).first!
254
268
  end
255
269
  end
256
270
  end
@@ -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.many", record: record)
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
- roots_to_validate.all? do |root|
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
@@ -1,3 +1,3 @@
1
1
  module AwesomeNestedSet
2
- VERSION = '3.0.3' unless defined?(::AwesomeNestedSet::VERSION)
2
+ VERSION = '3.1.3' unless defined?(::AwesomeNestedSet::VERSION)
3
3
  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.3
4
+ version: 3.1.3
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-01-19 00:00:00.000000000 Z
13
+ date: 2017-05-05 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.2'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
@@ -31,21 +31,63 @@ dependencies:
31
31
  version: 4.0.0
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
- version: '5'
34
+ version: '5.2'
35
+ - !ruby/object:Gem::Dependency
36
+ name: appraisal
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ type: :development
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ - !ruby/object:Gem::Dependency
50
+ name: pry
51
+ requirement: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: pry-nav
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
35
77
  - !ruby/object:Gem::Dependency
36
78
  name: rspec-rails
37
79
  requirement: !ruby/object:Gem::Requirement
38
80
  requirements:
39
81
  - - "~>"
40
82
  - !ruby/object:Gem::Version
41
- version: '3.0'
83
+ version: 3.5.0
42
84
  type: :development
43
85
  prerelease: false
44
86
  version_requirements: !ruby/object:Gem::Requirement
45
87
  requirements:
46
88
  - - "~>"
47
89
  - !ruby/object:Gem::Version
48
- version: '3.0'
90
+ version: 3.5.0
49
91
  - !ruby/object:Gem::Dependency
50
92
  name: rake
51
93
  requirement: !ruby/object:Gem::Requirement
@@ -67,6 +109,9 @@ dependencies:
67
109
  - - ">="
68
110
  - !ruby/object:Gem::Version
69
111
  version: 0.5.2
112
+ - - "<"
113
+ - !ruby/object:Gem::Version
114
+ version: 0.5.5
70
115
  type: :development
71
116
  prerelease: false
72
117
  version_requirements: !ruby/object:Gem::Requirement
@@ -74,6 +119,9 @@ dependencies:
74
119
  - - ">="
75
120
  - !ruby/object:Gem::Version
76
121
  version: 0.5.2
122
+ - - "<"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.5.5
77
125
  - !ruby/object:Gem::Dependency
78
126
  name: database_cleaner
79
127
  requirement: !ruby/object:Gem::Requirement
@@ -130,7 +178,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
130
178
  requirements:
131
179
  - - ">="
132
180
  - !ruby/object:Gem::Version
133
- version: 1.9.3
181
+ version: 2.0.0
134
182
  required_rubygems_version: !ruby/object:Gem::Requirement
135
183
  requirements:
136
184
  - - ">="
@@ -138,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
186
  version: '0'
139
187
  requirements: []
140
188
  rubyforge_project:
141
- rubygems_version: 2.5.1
189
+ rubygems_version: 2.6.6
142
190
  signing_key:
143
191
  specification_version: 4
144
192
  summary: An awesome nested set implementation for Active Record