rails_delete_all_and_assocs_without_instantiation 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29a1a21db1dd7be9228776c4dd8c0f62fe53e626292fdc3423a60659ffe6bfbb
4
- data.tar.gz: f1d447a7c617b90061ad3f836074449fed01d0bbf3fd2f98f1f6f50b027fb23b
3
+ metadata.gz: e9acdcdfc546fa1f49d03d2f52f785e8a012211cb2fead2ff5dad11767d125cc
4
+ data.tar.gz: e46db80ef699f7ad8a8ffbd4f9689f15c019826ad65acdbbd1d982cdaa423a52
5
5
  SHA512:
6
- metadata.gz: 4d4ca0d71e2f5f4916dedbf510478e3cd3b431f48116ff83479fa7f3502e2e5c0878833348827eb5f873f7c617c50095281abe72c936cbb6189c28ee67a7aa0c
7
- data.tar.gz: 16f5c31e7c3971094b98bf90ae3a9d40fc276a3b5abd5d29502484978143e2fdb0b05c635fe75aea604c42476ed191f1e809be3f9d2c25f289c6154cbfcb2555
6
+ metadata.gz: 87cdde62744d43c2567d6b55a59ccddcd0a412925c6d396294396839d12036dab633d3a3fd09d3284952bd5a351d4467c27d0426e5cf088b92b83963860f284c
7
+ data.tar.gz: 19ac4b45404cd36e02d1f1aac7cf8a9598a862ae272e32553258a377dbf2af8aa28ffc7047aa6e817898ab32fbb8922180b4b48bd5009d4243365fbb30187354
data/README.md CHANGED
@@ -36,3 +36,22 @@ class User < ApplicationRecord
36
36
  has_many :creator_accounts, -> (user_id) { where(creator_id: user_id) }, dependent: :destroy
37
37
  end
38
38
  ```
39
+
40
+ # Customization
41
+ ```
42
+ class User
43
+ # This is a way you can do more advanced filtering on association dependencies, and not just wipe everything
44
+ def self.delete_all_and_assocs_without_instantiation_builder models_and_ids_list = {}, errors = [], options = {}
45
+ original_account_ids = models_and_ids_list['Account']
46
+ models_and_ids_list, errors = super(models_and_ids_list, errors, options)
47
+ # we've ignored the deletion command that may or may not have been created by your assoc definition
48
+ models_and_ids_list['Account'] = original_account_ids
49
+
50
+ query = self.where({}).includes(:accounts).joins(:accounts).where(accounts: {marketable: true})
51
+ account_ids = query.collect{|pro| pro.accounts.map(&:id) }.flatten
52
+ models_and_ids_list, errors = Account.unscoped.where(id: account_ids).delete_all_and_assocs_without_instantiation_builder(models_and_ids_list, errors, options)
53
+
54
+ return models_and_ids_list, errors
55
+ end
56
+ end
57
+ ```
@@ -1,5 +1,13 @@
1
1
  module RailsDeleteAllAndAssocsWithoutInstantiation
2
2
  module DeleteAllAndAssocsWithoutInstantiation
3
+ MATCH_DEPENDENT_ASSOC_VALUE = [
4
+ :destroy,
5
+ 'destroy',
6
+ :delete_all,
7
+ 'delete_all',
8
+ :destroy_async,
9
+ 'destroy_async',
10
+ ]
3
11
 
4
12
  # rails interpretation is different than expected:
5
13
  # https://makandracards.com/makandra/32175-don-t-forget-automatically-remove-join-records-on-has_many-through-associations
@@ -22,25 +30,25 @@ module RailsDeleteAllAndAssocsWithoutInstantiation
22
30
  # force_through_destroy_chains = options[:force_destroy_chain] || {}
23
31
  # do_not_destroy_self = options[:do_not_destroy] || {}
24
32
 
25
- current_class = self::class
33
+ current_class = self.name
26
34
  current_query = self
27
35
  ids = current_query.pluck(:id)
28
36
  models_and_ids_list[name] ||= []
29
37
 
30
38
  # prevent infinite recursion here.
31
39
  ids = ids - models_and_ids_list[self.name]
32
- if ids.none?
40
+ if ids.none? || ids.nil?
33
41
  return models_and_ids_list, errors
34
42
  end
35
43
 
36
- models_and_ids_list[self.name] = ids
44
+ models_and_ids_list[self.name] += ids
37
45
 
38
46
  # if do_not_destroy_self != true
39
47
  # models_and_ids_list[name] += ids
40
48
  # end
41
49
 
42
50
  # ignore associations that aren't dependent destroyable.
43
- destroy_association_names = self.reflect_on_all_associations.reject{|v| ![:destroy, 'destroy'].include?(v.options&.dig(:dependent)) }.collect{ |v| v.name }
51
+ destroy_association_names = self.reflect_on_all_associations.reject{|v| !MATCH_DEPENDENT_ASSOC_VALUE.include?(v.options&.dig(:dependent)) }.collect{ |v| v.name }
44
52
 
45
53
 
46
54
  # associations that we might not necessarilly need to delete, but need to go through
@@ -145,24 +153,38 @@ module RailsDeleteAllAndAssocsWithoutInstantiation
145
153
  retry_due_to_errors = []
146
154
  retry_to_capture_errors = []
147
155
 
156
+ if options[:verbose]
157
+ puts "DELETION STRUCTURE"
158
+ puts built_deletions.inspect
159
+ end
160
+
148
161
  ActiveRecord::Base.transaction do
149
162
  built_deletions.keys.reverse.each do |class_name|
163
+ ids = "N/A"
150
164
  begin
151
165
  ids = built_deletions[class_name]
152
- next if ids.none?
166
+ next if ids.none? || ids.nil?
153
167
  klass = class_name.constantize
154
168
  klass.unscoped.where(id: ids).delete_all
155
169
  rescue Exception => e
170
+ puts "DEL ATTEMPT 1: #{class_name}.unscoped.where(id: #{ids}).delete_all" if options[:verbose]
156
171
  retry_due_to_errors << class_name
157
172
  end
158
173
  end
159
174
 
175
+ if options[:verbose]
176
+ puts "RETRY DUE TO ERRORS:"
177
+ puts retry_due_to_errors.inspect
178
+ end
179
+
160
180
  # ActiveRecord::InvalidForeignKey can cause issues in ordering.
161
- retry_due_to_errors.reverse.each do |class_name|
181
+ retry_due_to_errors.each do |class_name|
182
+ ids = "N/A"
162
183
  begin
163
184
  ids = built_deletions[class_name]
164
- next if ids.none?
185
+ next if ids.none? || ids.nil?
165
186
  klass = class_name.constantize
187
+ puts "DEL ATTEMPT 2: #{class_name}.unscoped.where(id: #{ids}).delete_all" if options[:verbose]
166
188
  klass.unscoped.where(id: ids).delete_all
167
189
  # if Rails.env.test? || Rails.env.development?
168
190
  # if count = klass.unscoped.where(id: ids).count > 0
@@ -172,20 +194,27 @@ module RailsDeleteAllAndAssocsWithoutInstantiation
172
194
  rescue Exception => e
173
195
  # ActiveRecord::Base.transaction obscures the actual errors
174
196
  # - need to run again outside of block to get actual error
175
- retry_to_capture_errors << [klass, ids]
197
+ retry_to_capture_errors << [class_name, ids]
176
198
  raise ActiveRecord::Rollback
177
199
  end
178
200
  end
179
201
  end
180
202
 
181
- retry_to_capture_errors.each do |klass, ids|
203
+ retry_to_capture_errors.each do |class_name, ids|
204
+ if ids == "N/A"
205
+ errors << ["Internal Server Error, could not locate IDs", class_name]
206
+ next
207
+ end
182
208
  begin
209
+ klass = class_name.constantize
210
+ puts "DEL ATTEMPT 3: #{class_name}.unscoped.where(id: #{ids}).delete_all" if options[:verbose]
183
211
  klass.unscoped.where(id: ids).delete_all
184
212
  # should never get past this line, we're expecting an error!
185
213
  # - if we do, maybe was an intermittent issue. Call ourselves recursively to try again.
186
- return current_query.delete_all_and_assocs_without_instantiation(options)
214
+ # return current_query.delete_all_and_assocs_without_instantiation(options)
215
+ errors << ["#{class_name} - expected error, ran into 2 errors on previous deletion attempts", ids]
187
216
  rescue Exception => e
188
- errors << e.class.to_s + "; " + e.message
217
+ errors << [e.class.to_s + "; " + e.message, e.backtrace]
189
218
  end
190
219
 
191
220
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{rails_delete_all_and_assocs_without_instantiation}
5
- s.version = "0.0.2"
5
+ s.version = "0.0.4"
6
6
  s.date = %q{2023-03-02}
7
7
  s.authors = ["benjamin.dana.software.dev@gmail.com"]
8
8
  s.summary = %q{Non-instantiated way of deleting records with dependencies quickly without instantiation.}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_delete_all_and_assocs_without_instantiation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - benjamin.dana.software.dev@gmail.com