delete_recursively 0.9.4 → 1.0.0
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.
- checksums.yaml +4 -4
- data/lib/delete_recursively.rb +134 -84
- metadata +40 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc815c840d3f1514a41c2254278aa84205aa1b29
|
4
|
+
data.tar.gz: 144a4055f89143dbd6e3744839fa7fe4897c6300
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91b7bc103274442ad9e424e4058b9bd7b66e460f98146ef0110e63bb6764e3f1b43fa0668ee7b017a5a3072840ca880e235f1f48324353ac2aecd7f5be440c7c
|
7
|
+
data.tar.gz: b07cbf652da91fcc0fe961affb61edef238097456c5fcc63cba249474b977e9631e62d93f9e5bc0e80637b798a01eb894d799f2520880ef7a61f6dd12bd1348d
|
data/lib/delete_recursively.rb
CHANGED
@@ -1,84 +1,134 @@
|
|
1
|
-
#
|
2
|
-
# DeleteRecursively
|
3
|
-
#
|
4
|
-
# Adds a new dependent: option to ActiveRecord associations.
|
5
|
-
#
|
6
|
-
module DeleteRecursively
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
ids =
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
1
|
+
#
|
2
|
+
# DeleteRecursively
|
3
|
+
#
|
4
|
+
# Adds a new dependent: option to ActiveRecord associations.
|
5
|
+
#
|
6
|
+
module DeleteRecursively
|
7
|
+
require_relative File.join('delete_recursively', 'version')
|
8
|
+
|
9
|
+
NEW_DEPENDENT_OPTION = :delete_recursively
|
10
|
+
|
11
|
+
# override ::valid_dependent_options to make the new
|
12
|
+
# dependent option available to Association::Builder classes
|
13
|
+
module OptionPermission
|
14
|
+
def valid_dependent_options
|
15
|
+
super + [NEW_DEPENDENT_OPTION]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# override Association#handle_dependency to apply the new option if it is set
|
20
|
+
module DependencyHandling
|
21
|
+
def handle_dependency
|
22
|
+
return super unless DeleteRecursively.enabled_for?(self)
|
23
|
+
if reflection.belongs_to?
|
24
|
+
# can't use ::dependent_ids, owner is already destroyed at this point
|
25
|
+
ids = load_target ? target.id : []
|
26
|
+
else
|
27
|
+
ids = DeleteRecursively.dependent_ids(owner.class, owner.id, reflection)
|
28
|
+
end
|
29
|
+
DeleteRecursively.delete_recursively(reflection, ids)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class << self
|
34
|
+
def delete_recursively(reflection, record_ids)
|
35
|
+
record_class = reflection.klass
|
36
|
+
if recurse_on?(reflection)
|
37
|
+
record_class.reflect_on_all_associations.each do |sub_reflection|
|
38
|
+
dependent_ids = dependent_ids(record_class, record_ids, sub_reflection)
|
39
|
+
delete_recursively(sub_reflection, dependent_ids)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
destroy_or_delete(reflection, record_class, record_ids)
|
43
|
+
end
|
44
|
+
|
45
|
+
def destroy_or_delete(reflection, record_class, record_ids)
|
46
|
+
if destructive?(reflection)
|
47
|
+
record_class.destroy(record_ids)
|
48
|
+
elsif enabled_for?(reflection) || deleting?(reflection)
|
49
|
+
record_class.delete(record_ids)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def recurse_on?(reflection)
|
54
|
+
enabled_for?(reflection) || destructive?(reflection)
|
55
|
+
end
|
56
|
+
|
57
|
+
def enabled_for?(reflection)
|
58
|
+
reflection.options[:dependent] == NEW_DEPENDENT_OPTION
|
59
|
+
end
|
60
|
+
|
61
|
+
def destructive?(reflection)
|
62
|
+
[:destroy, :destroy_all].include?(reflection.options[:dependent])
|
63
|
+
end
|
64
|
+
|
65
|
+
def deleting?(reflection)
|
66
|
+
[:delete, :delete_all].include?(reflection.options[:dependent])
|
67
|
+
end
|
68
|
+
|
69
|
+
def dependent_ids(owner_class, owner_ids, reflection)
|
70
|
+
if reflection.belongs_to?
|
71
|
+
owners_arel = owner_class.where(owner_class.primary_key => owner_ids)
|
72
|
+
owners_arel.pluck(reflection.association_foreign_key).compact
|
73
|
+
elsif reflection.through_reflection
|
74
|
+
dependent_ids_with_through_option(owner_class, owner_ids, reflection)
|
75
|
+
else
|
76
|
+
owner_foreign_key = foreign_key(owner_class, reflection)
|
77
|
+
reflection.klass.where(owner_foreign_key => owner_ids).ids
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def dependent_ids_with_through_option(owner_class, owner_ids, reflection)
|
82
|
+
through_reflection = reflection.through_reflection
|
83
|
+
owner_foreign_key = foreign_key(owner_class, through_reflection)
|
84
|
+
|
85
|
+
dependent_class = reflection.klass
|
86
|
+
dependent_through_reflection = inverse_through_reflection(reflection)
|
87
|
+
dependent_foreign_key =
|
88
|
+
foreign_key(dependent_class, dependent_through_reflection)
|
89
|
+
|
90
|
+
through_reflection.klass
|
91
|
+
.where(owner_foreign_key => owner_ids).pluck(dependent_foreign_key)
|
92
|
+
end
|
93
|
+
|
94
|
+
def inverse_through_reflection(reflection)
|
95
|
+
through_class = reflection.through_reflection.klass
|
96
|
+
reflection.klass.reflect_on_all_associations
|
97
|
+
.map(&:through_reflection)
|
98
|
+
.find { |tr| tr && tr.klass == through_class }
|
99
|
+
end
|
100
|
+
|
101
|
+
def foreign_key(owner_class, reflection)
|
102
|
+
custom_foreign_key = reflection && reflection.options[:foreign_key]
|
103
|
+
custom_foreign_key || owner_class.to_s.foreign_key
|
104
|
+
end
|
105
|
+
|
106
|
+
def all(record_class, criteria = {})
|
107
|
+
record_class.reflect_on_all_associations.each do |reflection|
|
108
|
+
if recurse_on?(reflection)
|
109
|
+
all(reflection.klass, criteria)
|
110
|
+
elsif deleting?(reflection)
|
111
|
+
delete_with_applicable_criteria(reflection.klass, criteria)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
delete_with_applicable_criteria(record_class, criteria)
|
115
|
+
end
|
116
|
+
|
117
|
+
def delete_with_applicable_criteria(record_class, criteria)
|
118
|
+
applicable_criteria = criteria.select do |column_name, _value|
|
119
|
+
record_class.column_names.include?(column_name.to_s)
|
120
|
+
end
|
121
|
+
record_class.where(applicable_criteria).delete_all
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
require 'active_record'
|
127
|
+
|
128
|
+
%w(BelongsTo HasMany HasOne).each do |assoc_name|
|
129
|
+
assoc_builder = ActiveRecord::Associations::Builder.const_get(assoc_name)
|
130
|
+
assoc_builder.singleton_class.prepend(DeleteRecursively::OptionPermission)
|
131
|
+
|
132
|
+
assoc_class = ActiveRecord::Associations.const_get("#{assoc_name}Association")
|
133
|
+
assoc_class.prepend(DeleteRecursively::DependencyHandling)
|
134
|
+
end
|
metadata
CHANGED
@@ -1,71 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: delete_recursively
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Janosch Müller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.1.14
|
20
|
+
- - "<"
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
22
|
+
version: 6.0.0
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 4.1.14
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 6.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: appraisal
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
23
36
|
requirements:
|
24
37
|
- - "~>"
|
25
38
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
39
|
+
version: '2.2'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2.2'
|
27
47
|
- !ruby/object:Gem::Dependency
|
28
48
|
name: codeclimate-test-reporter
|
29
49
|
requirement: !ruby/object:Gem::Requirement
|
30
50
|
requirements:
|
31
51
|
- - "~>"
|
32
52
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0
|
53
|
+
version: '1.0'
|
34
54
|
type: :development
|
35
55
|
prerelease: false
|
36
56
|
version_requirements: !ruby/object:Gem::Requirement
|
37
57
|
requirements:
|
38
58
|
- - "~>"
|
39
59
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0
|
60
|
+
version: '1.0'
|
41
61
|
- !ruby/object:Gem::Dependency
|
42
62
|
name: rails
|
43
63
|
requirement: !ruby/object:Gem::Requirement
|
44
64
|
requirements:
|
45
|
-
- - "
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 4.1.14
|
68
|
+
- - "<"
|
46
69
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
70
|
+
version: 6.0.0
|
48
71
|
type: :development
|
49
72
|
prerelease: false
|
50
73
|
version_requirements: !ruby/object:Gem::Requirement
|
51
74
|
requirements:
|
52
|
-
- - "
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 4.1.14
|
78
|
+
- - "<"
|
53
79
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
80
|
+
version: 6.0.0
|
55
81
|
- !ruby/object:Gem::Dependency
|
56
82
|
name: rake
|
57
83
|
requirement: !ruby/object:Gem::Requirement
|
58
84
|
requirements:
|
59
85
|
- - "~>"
|
60
86
|
- !ruby/object:Gem::Version
|
61
|
-
version: '11.
|
87
|
+
version: '11.3'
|
62
88
|
type: :development
|
63
89
|
prerelease: false
|
64
90
|
version_requirements: !ruby/object:Gem::Requirement
|
65
91
|
requirements:
|
66
92
|
- - "~>"
|
67
93
|
- !ruby/object:Gem::Version
|
68
|
-
version: '11.
|
94
|
+
version: '11.3'
|
69
95
|
- !ruby/object:Gem::Dependency
|
70
96
|
name: rspec
|
71
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,9 +162,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
162
|
version: '0'
|
137
163
|
requirements: []
|
138
164
|
rubyforge_project:
|
139
|
-
rubygems_version: 2.
|
165
|
+
rubygems_version: 2.6.11
|
140
166
|
signing_key:
|
141
167
|
specification_version: 4
|
142
168
|
summary: Delete ActiveRecords efficiently
|
143
169
|
test_files: []
|
144
|
-
has_rdoc:
|