@@ -116,10 +116,10 @@ def purge_by_scope(older_than = nil, window = nil, &block)
116
116
total
117
117
end
118
118
119
- def purge_by_orphaned ( fk_name , window = purge_window_size )
119
+ def purge_by_orphaned ( fk_name , window = purge_window_size , purge_mode = :purge )
120
120
_log . info ( "Purging orphans in #{ table_name } ..." )
121
- total = purge_orphans ( fk_name , window )
122
- _log . info ( "Purging orphans in #{ table_name } ...Complete - Deleted #{ total } records" )
121
+ total = purge_orphans ( fk_name , window , purge_mode )
122
+ _log . info ( "Purging orphans in #{ table_name } ...Complete - #{ purge_mode . to_sym == :count ? 'Would delete' : ' Deleted' } #{ total } records" )
123
123
total
124
124
end
125
125
@@ -133,23 +133,38 @@ def purge_by_date_and_orphaned(older_than, fk_name, window = purge_window_size)
133
133
134
134
private
135
135
136
- def purge_orphans ( fk_name , window )
137
- # For now, this only supports polymorphic references
138
- # We don't currently have a situation where a table with a regular reference needs to be purged
136
+ def purge_orphans ( fk_name , window , purge_mode = :purge )
137
+ reflection = reflect_on_association ( fk_name )
138
+ scopes = reflection . polymorphic? ? polymorphic_orphan_scopes ( fk_name ) : non_polymorphic_orphan_scopes ( fk_name , reflection . klass )
139
+
140
+ if purge_mode . to_sym == :count
141
+ scopes . sum ( &:count )
142
+ else
143
+ scopes . sum { |s | purge_in_batches ( s , window ) }
144
+ end
145
+ end
146
+
147
+ def polymorphic_orphan_scopes ( fk_name )
139
148
polymorphic_type_column = "#{ fk_name } _type"
140
149
polymorphic_id_column = connection . quote_column_name ( "#{ fk_name } _id" )
141
- total = 0
142
150
143
- polymorphic_classes ( polymorphic_type_column ) . each do |klass |
151
+ polymorphic_classes ( polymorphic_type_column ) . collect do |klass |
144
152
resource_table = connection . quote_table_name ( klass . table_name )
145
153
q_table_name = connection . quote_table_name ( table_name )
146
154
147
- scope = joins ( "LEFT OUTER JOIN #{ resource_table } ON #{ q_table_name } .#{ polymorphic_id_column } = #{ resource_table } .id" )
148
- . where ( resource_table => { :id => nil } )
149
- . where ( "#{ q_table_name } .#{ connection . quote_column_name ( polymorphic_type_column ) } = #{ connection . quote ( klass . name ) } " )
150
- total += purge_in_batches ( scope , window )
155
+ joins ( "LEFT OUTER JOIN #{ resource_table } ON #{ q_table_name } .#{ polymorphic_id_column } = #{ resource_table } .id" )
156
+ . where ( resource_table => { :id => nil } )
157
+ . where ( "#{ q_table_name } .#{ connection . quote_column_name ( polymorphic_type_column ) } = #{ connection . quote ( klass . name ) } " )
151
158
end
152
- total
159
+ end
160
+
161
+ def non_polymorphic_orphan_scopes ( fk_name , reflection_klass )
162
+ resource_table = connection . quote_table_name ( reflection_klass . table_name )
163
+ assoc_id = connection . quote_column_name ( "#{ fk_name } _id" )
164
+ q_table_name = connection . quote_table_name ( table_name )
165
+
166
+ [ joins ( "LEFT OUTER JOIN #{ resource_table } ON #{ q_table_name } .#{ assoc_id } = #{ resource_table } .id" )
167
+ . where ( resource_table => { :id => nil } ) ]
153
168
end
154
169
155
170
def polymorphic_classes ( polymorphic_type_column )
0 commit comments