File tree Expand file tree Collapse file tree 3 files changed +57
-4
lines changed Expand file tree Collapse file tree 3 files changed +57
-4
lines changed Original file line number Diff line number Diff line change @@ -112,11 +112,28 @@ module ClassMethods
112112 # Note that the hierarchy table will be truncated.
113113 def rebuild!
114114 _ct . with_advisory_lock do
115- hierarchy_class . delete_all # not destroy_all -- we just want a simple truncate.
115+ cleanup!
116116 roots . find_each { |n | n . send ( :rebuild! ) } # roots just uses the parent_id column, so this is safe.
117117 end
118118 nil
119119 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
120137 end
121138 end
122139end
Original file line number Diff line number Diff line change 143143 t . integer "generations" , :null => false
144144 end
145145
146- add_foreign_key ( :metal_hierarchies , :metal , :column => 'ancestor_id' )
147- add_foreign_key ( :metal_hierarchies , :metal , :column => 'descendant_id' )
148-
149146 create_table 'menu_items' do |t |
150147 t . string 'name'
151148 t . references 'parent'
Original file line number Diff line number Diff line change 1313 expect ( MetalHierarchy . count ) . to eq ( hierarchy_count )
1414 end
1515 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
1655end
You can’t perform that action at this time.
0 commit comments