closure_tree 3.7.1 → 3.7.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -396,6 +396,12 @@ Parallelism is not tested with Rails 3.0.x nor 3.1.x due to this
396
396
 
397
397
  ## Change log
398
398
 
399
+ ### 3.7.2
400
+
401
+ * Support for UUID primary keys. Addresses
402
+ [issue 40](https://github.com/mceachen/closure_tree/issues/40). Thanks for the pull request,
403
+ [Julien](https://github.com/calexicoz)!
404
+
399
405
  ### 3.7.1
400
406
 
401
407
  * Moved requires into ActiveSupport.on_load
@@ -550,4 +556,3 @@ a.save
550
556
  * https://github.com/patshaughnessy/class_factory
551
557
  * JetBrains, which provides an [open-source license](http://www.jetbrains.com/ruby/buy/buy.jsp#openSource) to
552
558
  [RubyMine](http://www.jetbrains.com/ruby/features/) for the development of this project.
553
-
@@ -237,7 +237,7 @@ module ClosureTree
237
237
  INNER JOIN (
238
238
  SELECT descendant_id
239
239
  FROM #{quoted_hierarchy_table_name}
240
- WHERE ancestor_id = #{self.id}
240
+ WHERE ancestor_id = #{ct_quote(self.id)}
241
241
  GROUP BY 1
242
242
  HAVING MAX(#{quoted_hierarchy_table_name}.generations) = #{generation_level.to_i}
243
243
  ) AS descendants ON (#{quoted_table_name}.#{ct_base_class.primary_key} = descendants.descendant_id)
@@ -290,9 +290,9 @@ module ClosureTree
290
290
  connection.execute <<-SQL
291
291
  INSERT INTO #{quoted_hierarchy_table_name}
292
292
  (ancestor_id, descendant_id, generations)
293
- SELECT x.ancestor_id, #{id}, x.generations + 1
293
+ SELECT x.ancestor_id, #{ct_quote(id)}, x.generations + 1
294
294
  FROM #{quoted_hierarchy_table_name} x
295
- WHERE x.descendant_id = #{self.ct_parent_id}
295
+ WHERE x.descendant_id = #{ct_quote(self.ct_parent_id)}
296
296
  SQL
297
297
  end
298
298
  children.each { |c| c.rebuild! }
@@ -316,9 +316,9 @@ module ClosureTree
316
316
  SELECT DISTINCT descendant_id
317
317
  FROM ( SELECT descendant_id
318
318
  FROM #{quoted_hierarchy_table_name}
319
- WHERE ancestor_id = #{id}
319
+ WHERE ancestor_id = #{ct_quote(id)}
320
320
  ) AS x )
321
- OR descendant_id = #{id}
321
+ OR descendant_id = #{ct_quote(id)}
322
322
  SQL
323
323
  end
324
324
 
@@ -334,6 +334,10 @@ module ClosureTree
334
334
  end
335
335
  end
336
336
 
337
+ def ct_quote(field)
338
+ self.class.connection.quote(field)
339
+ end
340
+
337
341
  # TODO: _parent_id will be removed in the next major version
338
342
  alias :_parent_id :ct_parent_id
339
343
 
@@ -1,3 +1,3 @@
1
1
  module ClosureTree
2
- VERSION = "3.7.1" unless defined?(::ClosureTree::VERSION)
2
+ VERSION = "3.7.2" unless defined?(::ClosureTree::VERSION)
3
3
  end
data/spec/db/schema.rb CHANGED
@@ -11,6 +11,22 @@ end
11
11
 
12
12
  ActiveRecord::Schema.define(:version => 0) do
13
13
 
14
+ create_table "nodes", :id => false do |t|
15
+ t.string "id"
16
+ t.string "name"
17
+ t.string "parent_id"
18
+ t.datetime "created_at"
19
+ t.datetime "updated_at"
20
+ end
21
+
22
+ force_add_index "nodes", [:id], :name => "node_id", :unique => true
23
+
24
+ create_table "node_hierarchies", :id => false, :force => true do |t|
25
+ t.string "ancestor_id", :null => false
26
+ t.string "descendant_id", :null => false
27
+ t.integer "generations", :null => false
28
+ end
29
+
14
30
  create_table "tags", :force => true do |t|
15
31
  t.string "name"
16
32
  t.string "title"
data/spec/node_spec.rb ADDED
@@ -0,0 +1,148 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for Node do
4
+
5
+ it "has correct accessible_attributes" do
6
+ Node.accessible_attributes.to_a.should =~ %w(parent name)
7
+ end
8
+
9
+ describe "empty db" do
10
+
11
+ def nuke_db
12
+ NodeHierarchy.delete_all
13
+ Node.delete_all
14
+ end
15
+
16
+ before :each do
17
+ nuke_db
18
+ end
19
+
20
+ context "empty db" do
21
+ it "should return no entities" do
22
+ Node.roots.should be_empty
23
+ Node.leaves.should be_empty
24
+ end
25
+ end
26
+
27
+ context "1 node db" do
28
+ it "should return the only entity as a root and leaf" do
29
+ a = Node.create!(:name => "a")
30
+ Node.roots.should == [a]
31
+ Node.leaves.should == [a]
32
+ end
33
+ end
34
+
35
+ context "2 node db" do
36
+ it "should return a simple root and leaf" do
37
+ root = Node.create!(:name => "root")
38
+ leaf = root.add_child(Node.create!(:name => "leaf"))
39
+ Node.roots.should == [root]
40
+ Node.leaves.should == [leaf]
41
+ end
42
+ end
43
+
44
+ context "3 node collection.create db" do
45
+ before :each do
46
+ @root = Node.create! :name => "root"
47
+ @mid = @root.children.create! :name => "mid"
48
+ @leaf = @mid.children.create! :name => "leaf"
49
+ end
50
+
51
+ it "should create all nodes" do
52
+ Node.all.should =~ [@root, @mid, @leaf]
53
+ end
54
+
55
+ it "should return a root and leaf without middle node" do
56
+ Node.roots.should == [@root]
57
+ Node.leaves.should == [@leaf]
58
+ end
59
+
60
+ it "should delete leaves" do
61
+ Node.leaves.destroy_all
62
+ Node.roots.should == [@root] # untouched
63
+ Node.leaves.should == [@mid]
64
+ end
65
+
66
+ it "should delete everything if you delete the roots" do
67
+ Node.roots.destroy_all
68
+ Node.all.should be_empty
69
+ Node.roots.should be_empty
70
+ Node.leaves.should be_empty
71
+ end
72
+ end
73
+
74
+ context "3 node explicit_create db" do
75
+ before :each do
76
+ @root = Node.create!(:name => "root")
77
+ @mid = @root.add_child(Node.create!(:name => "mid"))
78
+ @leaf = @mid.add_child(Node.create!(:name => "leaf"))
79
+ end
80
+
81
+ it "should create all nodes" do
82
+ Node.all.should =~ [@root, @mid, @leaf]
83
+ end
84
+
85
+ it "should return a root and leaf without middle node" do
86
+ Node.roots.should == [@root]
87
+ Node.leaves.should == [@leaf]
88
+ end
89
+
90
+ it "should prevent parental loops from torso" do
91
+ @mid.children << @root
92
+ @root.valid?.should be_false
93
+ @mid.reload.children.should == [@leaf]
94
+ end
95
+
96
+ it "should prevent parental loops from toes" do
97
+ @leaf.children << @root
98
+ @root.valid?.should be_false
99
+ @leaf.reload.children.should be_empty
100
+ end
101
+
102
+ it "should support re-parenting" do
103
+ @root.children << @leaf
104
+ Node.leaves.should =~ [@leaf, @mid]
105
+ end
106
+
107
+ it "cleans up hierarchy references for leaves" do
108
+ @leaf.destroy
109
+ NodeHierarchy.find_all_by_ancestor_id(@leaf.id).should be_empty
110
+ NodeHierarchy.find_all_by_descendant_id(@leaf.id).should be_empty
111
+ end
112
+
113
+ it "cleans up hierarchy references" do
114
+ @mid.destroy
115
+ NodeHierarchy.find_all_by_ancestor_id(@mid.id).should be_empty
116
+ NodeHierarchy.find_all_by_descendant_id(@mid.id).should be_empty
117
+ @root.reload.should be_root
118
+ root_hiers = @root.ancestor_hierarchies.to_a
119
+ root_hiers.size.should == 1
120
+ NodeHierarchy.find_all_by_ancestor_id(@root.id).should == root_hiers
121
+ NodeHierarchy.find_all_by_descendant_id(@root.id).should == root_hiers
122
+ end
123
+ end
124
+
125
+ it "performs as the readme says it does" do
126
+ grandparent = Node.create(:name => 'Grandparent')
127
+ parent = grandparent.children.create(:name => 'Parent')
128
+ child1 = Node.create(:name => 'First Child', :parent => parent)
129
+ child2 = Node.new(:name => 'Second Child')
130
+ parent.children << child2
131
+ child3 = Node.new(:name => 'Third Child')
132
+ parent.add_child child3
133
+ grandparent.self_and_descendants.collect(&:name).should ==
134
+ ["Grandparent", "Parent", "First Child", "Second Child", "Third Child"]
135
+ child1.ancestry_path.should ==
136
+ ["Grandparent", "Parent", "First Child"]
137
+ child3.ancestry_path.should ==
138
+ ["Grandparent", "Parent", "Third Child"]
139
+ d = Node.find_or_create_by_path %w(a b c d)
140
+ h = Node.find_or_create_by_path %w(e f g h)
141
+ e = h.root
142
+ d.add_child(e) # "d.children << e" would work too, of course
143
+ h.ancestry_path.should == %w(a b c d e f g h)
144
+ end
145
+
146
+ end
147
+
148
+ end
@@ -1,3 +1,15 @@
1
+ require 'uuidtools'
2
+
3
+ class Node < ActiveRecord::Base
4
+ acts_as_tree :dependent => :destroy
5
+ before_create :generate_uuid
6
+ attr_accessible :name
7
+
8
+ def generate_uuid
9
+ self.id = UUIDTools::UUID.random_create.to_s
10
+ end
11
+ end
12
+
1
13
  class Tag < ActiveRecord::Base
2
14
  acts_as_tree :dependent => :destroy, :order => "name"
3
15
  before_destroy :add_destroyed_tag
@@ -60,4 +72,4 @@ end
60
72
 
61
73
  class CuisineType < ActiveRecord::Base
62
74
  acts_as_tree
63
- end
75
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: closure_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.1
4
+ version: 3.7.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-26 00:00:00.000000000 Z
12
+ date: 2013-02-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -171,6 +171,22 @@ dependencies:
171
171
  - - ! '>='
172
172
  - !ruby/object:Gem::Version
173
173
  version: '0'
174
+ - !ruby/object:Gem::Dependency
175
+ name: uuidtools
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
174
190
  - !ruby/object:Gem::Dependency
175
191
  name: strong_parameters
176
192
  requirement: !ruby/object:Gem::Requirement
@@ -207,6 +223,7 @@ files:
207
223
  - spec/fixtures/tags.yml
208
224
  - spec/hash_tree_spec.rb
209
225
  - spec/label_spec.rb
226
+ - spec/node_spec.rb
210
227
  - spec/parallel_spec.rb
211
228
  - spec/spec_helper.rb
212
229
  - spec/support/models.rb
@@ -226,7 +243,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
226
243
  version: '0'
227
244
  segments:
228
245
  - 0
229
- hash: -469383754744352322
246
+ hash: -2260215237559696293
230
247
  required_rubygems_version: !ruby/object:Gem::Requirement
231
248
  none: false
232
249
  requirements:
@@ -235,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
252
  version: '0'
236
253
  segments:
237
254
  - 0
238
- hash: -469383754744352322
255
+ hash: -2260215237559696293
239
256
  requirements: []
240
257
  rubyforge_project:
241
258
  rubygems_version: 1.8.23
@@ -250,6 +267,7 @@ test_files:
250
267
  - spec/fixtures/tags.yml
251
268
  - spec/hash_tree_spec.rb
252
269
  - spec/label_spec.rb
270
+ - spec/node_spec.rb
253
271
  - spec/parallel_spec.rb
254
272
  - spec/spec_helper.rb
255
273
  - spec/support/models.rb