closure_tree 3.0.1 → 3.0.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.
data/README.md CHANGED
@@ -197,6 +197,10 @@ class WhatTag < Tag ; end
197
197
 
198
198
  * Support 3.2.0's fickle deprecation of InstanceMethods (Thanks, [jheiss](https://github.com/mceachen/closure_tree/pull/5))!
199
199
 
200
+ ### 3.0.2
201
+
202
+ * Fix for ancestry-loop detection (performed by a validation, not through raising an exception in before_save)
203
+
200
204
  ## Thanks to
201
205
 
202
206
  * https://github.com/collectiveidea/awesome_nested_set
@@ -27,9 +27,10 @@ module ClosureTree
27
27
 
28
28
  include ClosureTree::Model
29
29
 
30
- before_destroy :acts_as_tree_before_destroy
30
+ validate :acts_as_tree_validate
31
31
  before_save :acts_as_tree_before_save
32
32
  after_save :acts_as_tree_after_save
33
+ before_destroy :acts_as_tree_before_destroy
33
34
 
34
35
  belongs_to :parent,
35
36
  :class_name => ct_class.to_s,
@@ -162,16 +163,19 @@ module ClosureTree
162
163
 
163
164
  protected
164
165
 
165
- def acts_as_tree_before_save
166
- @was_new_record = new_record?
166
+ def acts_as_tree_validate
167
167
  if changes[parent_column_name] &&
168
168
  parent.present? &&
169
169
  parent.self_and_ancestors.include?(self)
170
- # TODO: raise Ouroboros or Philip J. Fry error:
171
- raise ActiveRecord::ActiveRecordError "You cannot add an ancestor as a descendant"
170
+ errors.add(parent_column_sym, "You cannot add an ancestor as a descendant")
172
171
  end
173
172
  end
174
173
 
174
+ def acts_as_tree_before_save
175
+ @was_new_record = new_record?
176
+ nil # AR will cancel the save if this is falsy
177
+ end
178
+
175
179
  def acts_as_tree_after_save
176
180
  rebuild! if changes[parent_column_name] || @was_new_record
177
181
  end
@@ -1,3 +1,3 @@
1
1
  module ClosureTree
2
- VERSION = "3.0.1" unless defined?(::ClosureTree::VERSION)
2
+ VERSION = "3.0.2" unless defined?(::ClosureTree::VERSION)
3
3
  end
@@ -83,16 +83,18 @@ describe "empty db" do
83
83
  Tag.leaves.should == [@leaf]
84
84
  end
85
85
 
86
- it "should prevent parental loops" do
87
- lambda do
88
- @mid.children << @root
89
- end.should raise_error
90
-
91
- lambda do
92
- @leaf.children << @root
93
- end.should raise_error
86
+ it "should prevent parental loops from torso" do
87
+ @mid.children << @root
88
+ @root.valid?.should be_false
89
+ @mid.reload.children.should == [@leaf]
94
90
  end
95
91
 
92
+ it "should prevent parental loops from toes" do
93
+ @leaf.children << @root
94
+ @root.valid?.should be_false
95
+ @leaf.reload.children.should be_empty
96
+ end
97
+
96
98
  it "should support reparenting" do
97
99
  @root.children << @leaf
98
100
  Tag.leaves.should =~ [@leaf, @mid]
@@ -168,9 +170,12 @@ describe Tag do
168
170
  end
169
171
 
170
172
  it "should fail to create ancestor loops" do
171
- lambda do
172
- tags(:child).add_child(tags(:grandparent))
173
- end.should raise_error
173
+ child = tags(:child)
174
+ parent = child.parent
175
+ child.add_child(parent) # this should fail
176
+ parent.valid?.should be_false
177
+ child.reload.children.should be_empty
178
+ parent.reload.children.should =~ [child]
174
179
  end
175
180
 
176
181
  it "should move non-leaves" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: closure_tree
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 1
10
- version: 3.0.1
9
+ - 2
10
+ version: 3.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matthew McEachen
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-30 00:00:00 Z
18
+ date: 2012-02-07 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  prerelease: false