closure_tree 3.5.1 → 3.5.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
@@ -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