File tree 3 files changed +57
-4
lines changed
3 files changed +57
-4
lines changed Original file line number Diff line number Diff line change @@ -112,11 +112,28 @@ module ClassMethods
112
112
# Note that the hierarchy table will be truncated.
113
113
def rebuild!
114
114
_ct . with_advisory_lock do
115
- hierarchy_class . delete_all # not destroy_all -- we just want a simple truncate.
115
+ cleanup!
116
116
roots . find_each { |n | n . send ( :rebuild! ) } # roots just uses the parent_id column, so this is safe.
117
117
end
118
118
nil
119
119
end
120
+
121
+ def cleanup!
122
+ hierarchy_table = hierarchy_class . arel_table
123
+
124
+ [ :descendant_id , :ancestor_id ] . each do |foreign_key |
125
+ alias_name = foreign_key . to_s . split ( '_' ) . first + "s"
126
+ alias_table = Arel ::Table . new ( table_name ) . alias ( alias_name )
127
+ arel_join = hierarchy_table . join ( alias_table , Arel ::Nodes ::OuterJoin )
128
+ . on ( alias_table [ primary_key ] . eq ( hierarchy_table [ foreign_key ] ) )
129
+ . join_sources
130
+
131
+ lonely_childs = hierarchy_class . joins ( arel_join ) . where ( alias_table [ primary_key ] . eq ( nil ) )
132
+ ids = lonely_childs . pluck ( foreign_key )
133
+
134
+ hierarchy_class . where ( hierarchy_table [ foreign_key ] . in ( ids ) ) . delete_all
135
+ end
136
+ end
120
137
end
121
138
end
122
139
end
Original file line number Diff line number Diff line change 143
143
t . integer "generations" , :null => false
144
144
end
145
145
146
- add_foreign_key ( :metal_hierarchies , :metal , :column => 'ancestor_id' )
147
- add_foreign_key ( :metal_hierarchies , :metal , :column => 'descendant_id' )
148
-
149
146
create_table 'menu_items' do |t |
150
147
t . string 'name'
151
148
t . references 'parent'
Original file line number Diff line number Diff line change 13
13
expect ( MetalHierarchy . count ) . to eq ( hierarchy_count )
14
14
end
15
15
end
16
+
17
+ describe '.cleanup!' do
18
+ let! ( :parent ) { Metal . create ( :value => "parent metal" ) }
19
+ let! ( :child ) { Metal . create ( :value => "child metal" , parent : parent ) }
20
+
21
+ before do
22
+ MetalHierarchy . delete_all
23
+ Metal . rebuild!
24
+ end
25
+
26
+ context 'when an element is deleted' do
27
+ it 'should delete the child hierarchies' do
28
+ child . delete
29
+
30
+ Metal . cleanup!
31
+
32
+ expect ( MetalHierarchy . where ( descendant_id : child . id ) ) . to be_empty
33
+ expect ( MetalHierarchy . where ( ancestor_id : child . id ) ) . to be_empty
34
+ end
35
+
36
+ it 'should not delete the parent hierarchies' do
37
+ child . delete
38
+ Metal . cleanup!
39
+ expect ( MetalHierarchy . where ( ancestor_id : parent . id ) . size ) . to eq 1
40
+ end
41
+
42
+ it 'should not delete other hierarchies' do
43
+ other_parent = Metal . create ( :value => "other parent metal" )
44
+ other_child = Metal . create ( :value => "other child metal" , parent : other_parent )
45
+ Metal . rebuild!
46
+
47
+ child . delete
48
+ Metal . cleanup!
49
+
50
+ expect ( MetalHierarchy . where ( ancestor_id : other_parent . id ) . size ) . to eq 2
51
+ expect ( MetalHierarchy . where ( descendant_id : other_child . id ) . size ) . to eq 2
52
+ end
53
+ end
54
+ end
16
55
end
You can’t perform that action at this time.
0 commit comments