closure_tree 3.5.1 → 3.5.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -331,7 +331,7 @@ Closure tree is [tested under every combination](http://travis-ci.org/#!/mceache
331
331
 
332
332
  ## Change log
333
333
 
334
- ### 3.5.1
334
+ ### 3.5.2
335
335
 
336
336
  * Added ```find_all_by_generation```
337
337
  for [feature request 17](https://github.com/mceachen/closure_tree/issues/17).
@@ -87,9 +87,24 @@ module ClosureTree
87
87
  roots.inject(ActiveSupport::OrderedHash.new) { |h, ea| h.merge(ea.hash_tree(options)) }
88
88
  end
89
89
 
90
- def self.find_all_by_generation(generation_level)
91
- # TODO: make this be a proper SQL select, not an inject.
92
- roots.inject([]) { |a, ea| a + ea.find_all_by_generation(generation_level).to_a }
90
+ def find_all_by_generation(generation_level)
91
+ s = joins(<<-SQL)
92
+ INNER JOIN (
93
+ SELECT #{primary_key} as root_id
94
+ FROM #{quoted_table_name}
95
+ WHERE #{quoted_parent_column_name} IS NULL
96
+ ) AS roots ON (1 = 1)
97
+ INNER JOIN (
98
+ SELECT ancestor_id, descendant_id
99
+ FROM #{quoted_hierarchy_table_name}
100
+ GROUP BY 1, 2
101
+ HAVING MAX(generations) = #{generation_level.to_i}
102
+ ) AS descendants ON (
103
+ #{quoted_table_name}.#{primary_key} = descendants.descendant_id
104
+ AND roots.root_id = descendants.ancestor_id
105
+ )
106
+ SQL
107
+ order_option ? s.order(order_option) : s
93
108
  end
94
109
 
95
110
  def self.leaves
@@ -99,7 +114,7 @@ module ClosureTree
99
114
  FROM #{quoted_hierarchy_table_name}
100
115
  GROUP BY 1
101
116
  HAVING MAX(#{quoted_hierarchy_table_name}.generations) = 0
102
- ) AS leaves ON #{quoted_table_name}.#{primary_key} = leaves.ancestor_id
117
+ ) AS leaves ON (#{quoted_table_name}.#{primary_key} = leaves.ancestor_id)
103
118
  SQL
104
119
  order_option ? s.order(order_option) : s
105
120
  end
@@ -218,7 +233,7 @@ module ClosureTree
218
233
  WHERE ancestor_id = #{self.id}
219
234
  GROUP BY 1
220
235
  HAVING MAX(#{quoted_hierarchy_table_name}.generations) = #{generation_level.to_i}
221
- ) AS descendants ON #{quoted_table_name}.#{self.class.primary_key} = descendants.descendant_id
236
+ ) AS descendants ON (#{quoted_table_name}.#{self.class.primary_key} = descendants.descendant_id)
222
237
  SQL
223
238
  order_option ? s.order(order_option) : s
224
239
  end
@@ -1,3 +1,3 @@
1
1
  module ClosureTree
2
- VERSION = "3.5.1" unless defined?(::ClosureTree::VERSION)
2
+ VERSION = "3.5.2" unless defined?(::ClosureTree::VERSION)
3
3
  end
@@ -64,46 +64,54 @@ describe Label do
64
64
  end
65
65
  end
66
66
  end
67
-
68
67
  context "find_all_by_generation" do
69
68
  before :all do
70
69
  nuke_db
71
- @d1 = Label.find_or_create_by_path %w(a b c1 d1)
72
- @d2 = Label.find_or_create_by_path %w(a b c2 d2)
70
+ @d1 = Label.find_or_create_by_path %w(a1 b1 c1 d1)
73
71
  @c1 = @d1.parent
72
+ @b1 = @c1.parent
73
+ @a1 = @b1.parent
74
+ @d2 = Label.find_or_create_by_path %w(a1 b1 c2 d2)
74
75
  @c2 = @d2.parent
75
- @b = @c1.parent
76
- @a = @b.parent
76
+ @d3 = Label.find_or_create_by_path %w(a2 b2 c3 d3)
77
+ @c3 = @d3.parent
78
+ @b2 = @c3.parent
79
+ @a2 = @b2.parent
80
+ Label.update_all("sort_order = id")
77
81
  end
78
82
 
79
83
  it "finds roots from the class method" do
80
- Label.find_all_by_generation(1).to_a.should == [@b]
84
+ Label.find_all_by_generation(0).to_a.should == [@a1, @a2]
81
85
  end
82
86
 
83
87
  it "finds roots from themselves" do
84
- @a.find_all_by_generation(0).to_a.should == [@a]
88
+ @a1.find_all_by_generation(0).to_a.should == [@a1]
85
89
  end
86
90
 
87
91
  it "finds itself for non-roots" do
88
- @b.find_all_by_generation(0).to_a.should == [@b]
92
+ @b1.find_all_by_generation(0).to_a.should == [@b1]
89
93
  end
90
94
 
91
95
  it "finds children for roots" do
92
- Label.find_all_by_generation(1).to_a.should == [@b]
96
+ Label.find_all_by_generation(1).to_a.should == [@b1, @b2]
93
97
  end
94
98
 
95
99
  it "finds children" do
96
- @a.find_all_by_generation(1).to_a.should == [@b]
97
- @b.find_all_by_generation(1).to_a.should == [@c1, @c2]
100
+ @a1.find_all_by_generation(1).to_a.should == [@b1]
101
+ @b1.find_all_by_generation(1).to_a.should == [@c1, @c2]
98
102
  end
99
103
 
100
104
  it "finds grandchildren for roots" do
101
- Label.find_all_by_generation(2).to_a.should == [@c1, @c2]
105
+ Label.find_all_by_generation(2).to_a.should == [@c1, @c2, @c3]
102
106
  end
103
107
 
104
108
  it "finds grandchildren" do
105
- @a.find_all_by_generation(2).to_a.should == [@c1, @c2]
106
- @b.find_all_by_generation(2).to_a.should == [@d1, @d2]
109
+ @a1.find_all_by_generation(2).to_a.should == [@c1, @c2]
110
+ @b1.find_all_by_generation(2).to_a.should == [@d1, @d2]
111
+ end
112
+
113
+ it "finds great-grandchildren for roots" do
114
+ Label.find_all_by_generation(3).to_a.should == [@d1, @d2, @d3]
107
115
  end
108
116
  end
109
117
 
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.5.1
4
+ version: 3.5.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -192,7 +192,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
192
192
  version: '0'
193
193
  segments:
194
194
  - 0
195
- hash: 10070411071183028
195
+ hash: 4543577055875281407
196
196
  required_rubygems_version: !ruby/object:Gem::Requirement
197
197
  none: false
198
198
  requirements:
@@ -201,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
201
  version: '0'
202
202
  segments:
203
203
  - 0
204
- hash: 10070411071183028
204
+ hash: 4543577055875281407
205
205
  requirements: []
206
206
  rubyforge_project:
207
207
  rubygems_version: 1.8.23