kakurenbo 0.1.1 → 0.1.2
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/README.md +11 -0
- data/lib/kakurenbo/mixin_ar_base.rb +3 -3
- data/lib/kakurenbo/soft_delete_core.rb +62 -24
- data/lib/kakurenbo/version.rb +1 -1
- data/spec/kakurenbo/soft_delete_cores/associations_spec.rb +270 -0
- data/spec/kakurenbo/soft_delete_cores/callbacks_spec.rb +38 -0
- data/spec/kakurenbo/soft_delete_cores/core_spec.rb +229 -0
- data/spec/kakurenbo/soft_delete_cores/scopes_spec.rb +60 -0
- metadata +10 -4
- data/spec/kakurenbo/soft_delete_core_spec.rb +0 -420
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1db2fcbe670f950ac46f450c5365921042ec298b
|
4
|
+
data.tar.gz: b52de24c10f252966d25f629b86679142fcb0024
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad49f6368d5bd864abbe3847ceeae2db12f0df1a55977fc3de36b94758ea6ce561be9e60504e4218f40afaba2c29b174cc1122fc71bc8c7f936fa716e664fbec
|
7
|
+
data.tar.gz: 7f198fd7fb0ab7a0cd41e17ffcffe8f2c3e8464759d0db95cc7334c79202765f57195afdbd628bb8a1a3311f8021e3122d69e0b89b895db26121b97498933575
|
data/README.md
CHANGED
@@ -31,6 +31,16 @@ _Kakurenbo provides `acts_as_paranoid` method for compatibility._
|
|
31
31
|
|
32
32
|
``` ruby
|
33
33
|
model.destroy
|
34
|
+
|
35
|
+
# This is usable, too.
|
36
|
+
Model.destroy(id)
|
37
|
+
Model.destroy([id1,id2,id3])
|
38
|
+
```
|
39
|
+
|
40
|
+
when want without callbacks.
|
41
|
+
|
42
|
+
``` ruby
|
43
|
+
model.delete
|
34
44
|
```
|
35
45
|
|
36
46
|
### restore a record
|
@@ -40,6 +50,7 @@ model.restore!
|
|
40
50
|
|
41
51
|
# This is usable, too.
|
42
52
|
Model.restore(id)
|
53
|
+
Model.restore([id1,id2,id3])
|
43
54
|
```
|
44
55
|
|
45
56
|
When restore, call restore callbacks.`before_restore` `after_restore`
|
@@ -13,7 +13,7 @@ module Kakurenbo
|
|
13
13
|
next unless column_names.include?('deleted_at')
|
14
14
|
remodel_as_soft_delete
|
15
15
|
rescue
|
16
|
-
# When migrate.
|
16
|
+
# When exec first db:migrate and db:migrate:reset.
|
17
17
|
end
|
18
18
|
}
|
19
19
|
super
|
@@ -31,8 +31,8 @@ module Kakurenbo
|
|
31
31
|
)
|
32
32
|
|
33
33
|
unless paranoid?
|
34
|
-
alias_method :
|
35
|
-
alias_method :
|
34
|
+
alias_method :hard_delete!, :delete
|
35
|
+
alias_method :hard_destroy!, :destroy
|
36
36
|
|
37
37
|
class_attribute :kakurenbo_column
|
38
38
|
self.kakurenbo_column = options[:column]
|
@@ -5,6 +5,7 @@ module Kakurenbo
|
|
5
5
|
base_class.extend ClassMethods
|
6
6
|
base_class.extend Callbacks
|
7
7
|
base_class.extend Scopes
|
8
|
+
base_class.extend Aliases
|
8
9
|
end
|
9
10
|
|
10
11
|
module ClassMethods
|
@@ -12,12 +13,23 @@ module Kakurenbo
|
|
12
13
|
true
|
13
14
|
end
|
14
15
|
|
15
|
-
#
|
16
|
+
# Destroy model(s).
|
16
17
|
#
|
17
|
-
# @param id
|
18
|
+
# @param id [Array<Integer> or Integer] id or ids
|
19
|
+
def destroy(id)
|
20
|
+
transaction do
|
21
|
+
where(:id => id).each{|m| m.destroy}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Restore model(s).
|
26
|
+
#
|
27
|
+
# @param id [Array<Integer> or Integer] id or ids.
|
18
28
|
# @param options [Hash] options(same restore of instance methods.)
|
19
|
-
def restore(id, options = {})
|
20
|
-
|
29
|
+
def restore(id, options = {:recursive => true})
|
30
|
+
transaction do
|
31
|
+
only_deleted.where(:id => id).each{|m| m.restore!(options)}
|
32
|
+
end
|
21
33
|
end
|
22
34
|
end
|
23
35
|
|
@@ -45,6 +57,17 @@ module Kakurenbo
|
|
45
57
|
end
|
46
58
|
end
|
47
59
|
|
60
|
+
module Aliases
|
61
|
+
def self.extended(base_class)
|
62
|
+
base_class.instance_eval {
|
63
|
+
alias_method :delete!, :hard_delete!
|
64
|
+
alias_method :deleted?, :destroyed?
|
65
|
+
alias_method :restore, :restore!
|
66
|
+
alias_method :recover, :restore!
|
67
|
+
}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
48
71
|
def delete
|
49
72
|
return if new_record? or destroyed?
|
50
73
|
update_column kakurenbo_column, current_time_from_proper_timezone
|
@@ -52,16 +75,22 @@ module Kakurenbo
|
|
52
75
|
|
53
76
|
def destroy
|
54
77
|
return if destroyed?
|
55
|
-
with_transaction_returning_status
|
78
|
+
with_transaction_returning_status do
|
56
79
|
destroy_at = current_time_from_proper_timezone
|
57
80
|
run_callbacks(:destroy){ update_column kakurenbo_column, destroy_at }
|
58
|
-
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def destroy!
|
85
|
+
with_transaction_returning_status do
|
86
|
+
hard_destroy_associated_records
|
87
|
+
self.reload.hard_destroy!
|
88
|
+
end
|
59
89
|
end
|
60
90
|
|
61
91
|
def destroyed?
|
62
92
|
!send(kakurenbo_column).nil?
|
63
93
|
end
|
64
|
-
alias_method :deleted?, :destroyed?
|
65
94
|
|
66
95
|
def kakurenbo_column
|
67
96
|
self.class.kakurenbo_column
|
@@ -77,22 +106,32 @@ module Kakurenbo
|
|
77
106
|
# defaults: {
|
78
107
|
# recursive: true
|
79
108
|
# }
|
80
|
-
def restore!(options = {})
|
81
|
-
|
82
|
-
:recursive => true
|
83
|
-
)
|
84
|
-
|
85
|
-
with_transaction_returning_status {
|
109
|
+
def restore!(options = {:recursive => true})
|
110
|
+
with_transaction_returning_status do
|
86
111
|
run_callbacks(:restore) do
|
87
112
|
parent_deleted_at = send(kakurenbo_column)
|
88
113
|
update_column kakurenbo_column, nil
|
89
114
|
restore_associated_records(parent_deleted_at) if options[:recursive]
|
90
115
|
end
|
91
|
-
|
116
|
+
end
|
92
117
|
end
|
93
|
-
alias_method :restore, :restore!
|
94
118
|
|
95
119
|
private
|
120
|
+
# get recoreds of association.
|
121
|
+
#
|
122
|
+
# @param association [ActiveRecord::Associations] association.
|
123
|
+
# @return [Array or CollectionProxy] records.
|
124
|
+
def associated_records(association)
|
125
|
+
resource = send(association.name)
|
126
|
+
if resource.nil?
|
127
|
+
[]
|
128
|
+
elsif association.collection?
|
129
|
+
resource.with_deleted
|
130
|
+
else
|
131
|
+
[resource]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
96
135
|
# Calls the given block once for each dependent destroy records.
|
97
136
|
# @note Only call the class of paranoid.
|
98
137
|
#
|
@@ -102,16 +141,14 @@ module Kakurenbo
|
|
102
141
|
next unless association.options[:dependent] == :destroy
|
103
142
|
next unless association.klass.paranoid?
|
104
143
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
if association.collection?
|
109
|
-
resource = resource.only_deleted
|
110
|
-
else
|
111
|
-
resource = (resource.destroyed?) ? [resource] : []
|
112
|
-
end
|
144
|
+
associated_records(association).each &block
|
145
|
+
end
|
146
|
+
end
|
113
147
|
|
114
|
-
|
148
|
+
# Hard-Destroy associated records.
|
149
|
+
def hard_destroy_associated_records
|
150
|
+
each_dependent_destroy_records do |record|
|
151
|
+
record.destroy!
|
115
152
|
end
|
116
153
|
end
|
117
154
|
|
@@ -121,6 +158,7 @@ module Kakurenbo
|
|
121
158
|
# @param parent_deleted_at [Time] The time when parent was deleted.
|
122
159
|
def restore_associated_records(parent_deleted_at)
|
123
160
|
each_dependent_destroy_records do |record|
|
161
|
+
next unless record.destroyed?
|
124
162
|
next unless parent_deleted_at <= record.send(kakurenbo_column)
|
125
163
|
record.restore!
|
126
164
|
end
|
data/lib/kakurenbo/version.rb
CHANGED
@@ -0,0 +1,270 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Kakurenbo::SoftDeleteCore do
|
4
|
+
create_temp_table(:parent_models) { |t| t.integer :child_id; t.datetime :deleted_at }
|
5
|
+
create_temp_table(:normal_child_models) { |t| t.integer :parent_model_id }
|
6
|
+
create_temp_table(:paranoid_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
|
7
|
+
create_temp_table(:paranoid_single_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
class NormalChildModel < ActiveRecord::Base; end
|
11
|
+
class ParanoidChildModel < ActiveRecord::Base; end
|
12
|
+
class ParanoidSingleChildModel < ActiveRecord::Base; end
|
13
|
+
class ParentModel < ActiveRecord::Base
|
14
|
+
has_many :normal_child_models, :dependent => :destroy
|
15
|
+
has_many :paranoid_child_models, :dependent => :destroy
|
16
|
+
|
17
|
+
has_one :paranoid_single_child_model, :dependent => :destroy
|
18
|
+
belongs_to :child, :class_name => :ParanoidSingleChildModel, :dependent => :destroy
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
after :each do
|
23
|
+
Object.class_eval do
|
24
|
+
remove_const :NormalChildModel
|
25
|
+
remove_const :ParanoidChildModel
|
26
|
+
remove_const :ParanoidSingleChildModel
|
27
|
+
remove_const :ParentModel
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'NormalChildModel' do
|
32
|
+
before :each do
|
33
|
+
@parent = ParentModel.create!
|
34
|
+
@first = @parent.normal_child_models.create!
|
35
|
+
@second = @parent.normal_child_models.create!
|
36
|
+
|
37
|
+
@hitori = NormalChildModel.create!
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when parent be destroyed' do
|
41
|
+
it 'destroy children who parent has.' do
|
42
|
+
expect{@parent.destroy}.to change(NormalChildModel, :count).by(-2)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'not destroy children who parent does not have.' do
|
46
|
+
@parent.destroy
|
47
|
+
expect(@hitori.reload.destroyed?).to be_false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'ParanoidChildModel' do
|
53
|
+
before :each do
|
54
|
+
@parent = ParentModel.create!
|
55
|
+
@first = @parent.paranoid_child_models.create!
|
56
|
+
@second = @parent.paranoid_child_models.create!
|
57
|
+
@third = @parent.paranoid_child_models.create!
|
58
|
+
|
59
|
+
@hitori = ParanoidChildModel.create!
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when parent be destroyed' do
|
63
|
+
it 'destroy children who parent has.' do
|
64
|
+
expect{@parent.destroy}.to change(ParanoidChildModel, :count).by(-3)
|
65
|
+
expect(@first.reload.destroyed?).to be_true
|
66
|
+
expect(@second.reload.destroyed?).to be_true
|
67
|
+
expect(@third.reload.destroyed?).to be_true
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'not destroy children who parent does not have.' do
|
71
|
+
@parent.destroy
|
72
|
+
expect(@hitori.reload.destroyed?).to be_false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when parent be restored' do
|
77
|
+
before :each do
|
78
|
+
@parent.destroy
|
79
|
+
@hitori.destroy
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'restore children who parent has.' do
|
83
|
+
expect{@parent.restore!}.to change(ParanoidChildModel, :count).by(3)
|
84
|
+
expect(@first.reload.destroyed?).to be_false
|
85
|
+
expect(@second.reload.destroyed?).to be_false
|
86
|
+
expect(@third.reload.destroyed?).to be_false
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'not restore children who parent does not have.' do
|
90
|
+
@parent.restore!
|
91
|
+
expect(@hitori.reload.destroyed?).to be_true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'when delete child before parent was deleted' do
|
96
|
+
before :each do
|
97
|
+
# First, delete child.
|
98
|
+
delete_at = 1.second.ago
|
99
|
+
Time.stub(:now).and_return(delete_at)
|
100
|
+
@first.destroy
|
101
|
+
|
102
|
+
# Next, delete parent.
|
103
|
+
Time.unstub(:now)
|
104
|
+
@parent.destroy
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'not restore child who deleted before parent was deleted' do
|
108
|
+
expect{@parent.restore!}.to change(ParanoidChildModel, :count).by(2)
|
109
|
+
expect(@first.reload.destroyed?).to be_true
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'restore children who deleted after parent was deleted' do
|
113
|
+
expect{@parent.restore!}.to change(ParanoidChildModel, :count).by(2)
|
114
|
+
expect(@second.reload.destroyed?).to be_false
|
115
|
+
expect(@third.reload.destroyed?).to be_false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe 'ParanoidSingleChildModel(has_one)' do
|
121
|
+
before :each do
|
122
|
+
@parent = ParentModel.create!
|
123
|
+
@first = ParanoidSingleChildModel.create!(parent_model_id: @parent.id)
|
124
|
+
|
125
|
+
@hitori = ParanoidSingleChildModel.create!
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'when parent be destroyed' do
|
129
|
+
it 'destroy child who parent has.' do
|
130
|
+
expect{@parent.destroy}.to change(ParanoidSingleChildModel, :count).by(-1)
|
131
|
+
expect(@first.reload.destroyed?).to be_true
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'not destroy child who parent does not have.' do
|
135
|
+
@parent.destroy
|
136
|
+
expect(@hitori.reload.destroyed?).to be_false
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'when parent be restored' do
|
141
|
+
before :each do
|
142
|
+
@parent.destroy
|
143
|
+
@hitori.destroy
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'restore child who parent has.' do
|
147
|
+
expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(1)
|
148
|
+
expect(@first.reload.destroyed?).to be_false
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'not restore child who parent does not have.' do
|
152
|
+
@parent.restore
|
153
|
+
expect(@hitori.reload.destroyed?).to be_true
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when delete child before parent was deleted' do
|
158
|
+
before :each do
|
159
|
+
# First, delete child.
|
160
|
+
delete_at = 1.second.ago
|
161
|
+
Time.stub(:now).and_return(delete_at)
|
162
|
+
@first.destroy
|
163
|
+
|
164
|
+
# Next, delete parent.
|
165
|
+
Time.unstub(:now)
|
166
|
+
@parent.destroy
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'not restore child who deleted before parent was deleted' do
|
170
|
+
expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(0)
|
171
|
+
expect(@first.reload.destroyed?).to be_true
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'ParanoidSingleChildModel(belongs_to)' do
|
177
|
+
before :each do
|
178
|
+
@first = ParanoidSingleChildModel.create!
|
179
|
+
@parent = ParentModel.create!(child_id: @first.id)
|
180
|
+
|
181
|
+
@hitori = ParanoidSingleChildModel.create!
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'when parent be destroyed' do
|
185
|
+
it 'destroy child who parent has.' do
|
186
|
+
expect{@parent.destroy}.to change(ParanoidSingleChildModel, :count).by(-1)
|
187
|
+
expect(@first.reload.destroyed?).to be_true
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'not destroy child who parent does not have.' do
|
191
|
+
@parent.destroy
|
192
|
+
expect(@hitori.reload.destroyed?).to be_false
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'when parent be restored' do
|
197
|
+
before :each do
|
198
|
+
@parent.destroy
|
199
|
+
@hitori.destroy
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'restore child who parent has.' do
|
203
|
+
expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(1)
|
204
|
+
expect(@first.reload.destroyed?).to be_false
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'not restore child who parent does not have.' do
|
208
|
+
@parent.restore
|
209
|
+
expect(@hitori.reload.destroyed?).to be_true
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context 'when delete child before parent was deleted' do
|
214
|
+
before :each do
|
215
|
+
# First, delete child.
|
216
|
+
delete_at = 1.second.ago
|
217
|
+
Time.stub(:now).and_return(delete_at)
|
218
|
+
@first.destroy
|
219
|
+
|
220
|
+
# Next, delete parent.
|
221
|
+
Time.unstub(:now)
|
222
|
+
@parent.destroy
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'not restore child who deleted before parent was deleted' do
|
226
|
+
expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(0)
|
227
|
+
expect(@first.reload.destroyed?).to be_true
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe 'ChildModels' do
|
233
|
+
before :each do
|
234
|
+
@parent = ParentModel.create!
|
235
|
+
|
236
|
+
@normal_first = @parent.normal_child_models.create!
|
237
|
+
@normal_second = @parent.normal_child_models.create!
|
238
|
+
|
239
|
+
@paranoid_first = @parent.paranoid_child_models.create!
|
240
|
+
@paranoid_second = @parent.paranoid_child_models.create!
|
241
|
+
|
242
|
+
@single_first = ParanoidSingleChildModel.create!(parent_model_id: @parent.id)
|
243
|
+
|
244
|
+
@normal_hitori = NormalChildModel.create!
|
245
|
+
@paranoid_hitori = ParanoidChildModel.create!
|
246
|
+
@single_hitori = ParanoidSingleChildModel.create!
|
247
|
+
end
|
248
|
+
|
249
|
+
context 'when parent be hard-destroyed' do
|
250
|
+
it 'hard-destroy normal children who parent has.' do
|
251
|
+
expect{@parent.destroy!}.to change(NormalChildModel, :count).by(-2)
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'hard-destroy paranoid children who parent has.' do
|
255
|
+
expect{@parent.destroy!}.to change{ParanoidChildModel.with_deleted.count}.by(-2)
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'hard-destroy paranoid single child who parent has.' do
|
259
|
+
expect{@parent.destroy!}.to change{ParanoidSingleChildModel.with_deleted.count}.by(-1)
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'not destroy child who parent does not have.' do
|
263
|
+
@parent.destroy!
|
264
|
+
expect(@normal_hitori.reload.destroyed?).to be_false
|
265
|
+
expect(@paranoid_hitori.reload.destroyed?).to be_false
|
266
|
+
expect(@single_hitori.reload.destroyed?).to be_false
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Kakurenbo::SoftDeleteCore::Callbacks do
|
4
|
+
create_temp_table(:paranoid_models){ |t| t.datetime :deleted_at }
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
class ParanoidModel < ActiveRecord::Base; end
|
8
|
+
end
|
9
|
+
|
10
|
+
after :each do
|
11
|
+
Object.class_eval{ remove_const :ParanoidModel }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when run callback of restore' do
|
15
|
+
before :each do
|
16
|
+
@callback_model = ParanoidModel.create!
|
17
|
+
end
|
18
|
+
|
19
|
+
after :each do
|
20
|
+
@callback_model.run_callbacks(:restore)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'call before_restore.' do
|
24
|
+
ParanoidModel.before_restore :before_restore_callback
|
25
|
+
@callback_model.should_receive(:before_restore_callback).once
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'call around_restore.' do
|
29
|
+
ParanoidModel.around_restore :around_restore_callback
|
30
|
+
@callback_model.should_receive(:around_restore_callback).once
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'call after_restore.' do
|
34
|
+
ParanoidModel.after_restore :after_restore_callback
|
35
|
+
@callback_model.should_receive(:after_restore_callback).once
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Kakurenbo::SoftDeleteCore do
|
4
|
+
create_temp_table(:paranoid_models){ |t| t.datetime :deleted_at }
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
class ParanoidModel < ActiveRecord::Base; end
|
8
|
+
end
|
9
|
+
|
10
|
+
after :each do
|
11
|
+
Object.class_eval{ remove_const :ParanoidModel }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'Instance of paranoid model' do
|
15
|
+
before :each do
|
16
|
+
@model = ParanoidModel.create!
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when delete' do
|
20
|
+
it 'soft-delete model.' do
|
21
|
+
expect{
|
22
|
+
@model.delete
|
23
|
+
}.to change(ParanoidModel, :count).by(-1)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'not hard-delete model.' do
|
27
|
+
expect{
|
28
|
+
@model.delete
|
29
|
+
}.to change{
|
30
|
+
ParanoidModel.all.with_deleted.count
|
31
|
+
}.by(0)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'call callbacks nothing.' do
|
35
|
+
ParanoidModel.before_destroy :before_destroy_callback
|
36
|
+
ParanoidModel.after_destroy :after_destroy_callback
|
37
|
+
ParanoidModel.after_commit :after_commit_callback
|
38
|
+
|
39
|
+
@model.should_receive(:before_destroy_callback).exactly(0).times
|
40
|
+
@model.should_receive(:after_destroy_callback).exactly(0).times
|
41
|
+
@model.should_receive(:after_commit_callback).exactly(0).times
|
42
|
+
|
43
|
+
@model.delete
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'not call callbacks other.' do
|
47
|
+
ParanoidModel.before_update :before_update_callback
|
48
|
+
ParanoidModel.before_save :before_save_callback
|
49
|
+
ParanoidModel.validate :validate_callback
|
50
|
+
|
51
|
+
@model.should_receive(:before_update_callback).exactly(0).times
|
52
|
+
@model.should_receive(:before_save_callback).exactly(0).times
|
53
|
+
@model.should_receive(:validate_callback).exactly(0).times
|
54
|
+
|
55
|
+
@model.delete
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when delete!' do
|
60
|
+
it 'hard-delete model.' do
|
61
|
+
expect{
|
62
|
+
@model.delete!
|
63
|
+
}.to change{
|
64
|
+
ParanoidModel.all.with_deleted.count
|
65
|
+
}.by(-1)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'when destroy(class method)' do
|
70
|
+
before :each do
|
71
|
+
@model2 = ParanoidModel.create!
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'with id, destroy model.' do
|
75
|
+
expect{
|
76
|
+
ParanoidModel.destroy(@model.id)
|
77
|
+
}.to change(ParanoidModel, :count).by(-1)
|
78
|
+
|
79
|
+
expect(@model.reload.destroyed?).to be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'with ids, destroy models.' do
|
83
|
+
expect{
|
84
|
+
ParanoidModel.destroy([@model.id, @model2.id])
|
85
|
+
}.to change(ParanoidModel, :count).by(-2)
|
86
|
+
|
87
|
+
expect(@model.reload.destroyed?).to be_true
|
88
|
+
expect(@model2.reload.destroyed?).to be_true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'when destroy(instance method)' do
|
93
|
+
it 'soft-delete model.' do
|
94
|
+
expect{
|
95
|
+
@model.destroy
|
96
|
+
}.to change(ParanoidModel, :count).by(-1)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'not hard-delete model.' do
|
100
|
+
expect{
|
101
|
+
@model.destroy
|
102
|
+
}.to change{
|
103
|
+
ParanoidModel.all.with_deleted.count
|
104
|
+
}.by(0)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'call callbacks of destroy.' do
|
108
|
+
ParanoidModel.before_destroy :before_destroy_callback
|
109
|
+
ParanoidModel.after_destroy :after_destroy_callback
|
110
|
+
ParanoidModel.after_commit :after_commit_callback
|
111
|
+
|
112
|
+
@model.should_receive(:before_destroy_callback).once
|
113
|
+
@model.should_receive(:after_destroy_callback).once
|
114
|
+
@model.should_receive(:after_commit_callback).once.and_return(true)
|
115
|
+
|
116
|
+
@model.destroy
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'not call callbacks without destroy.' do
|
120
|
+
ParanoidModel.before_update :before_update_callback
|
121
|
+
ParanoidModel.before_save :before_save_callback
|
122
|
+
ParanoidModel.validate :validate_callback
|
123
|
+
|
124
|
+
@model.should_receive(:before_update_callback).exactly(0).times
|
125
|
+
@model.should_receive(:before_save_callback).exactly(0).times
|
126
|
+
@model.should_receive(:validate_callback).exactly(0).times
|
127
|
+
|
128
|
+
@model.destroy
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'when destroy!' do
|
133
|
+
it 'hard-delete model.' do
|
134
|
+
expect{
|
135
|
+
@model.destroy!
|
136
|
+
}.to change{
|
137
|
+
ParanoidModel.all.with_deleted.count
|
138
|
+
}.by(-1)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'when destroyed?' do
|
143
|
+
it 'false if model not destroyed.' do
|
144
|
+
expect(@model.destroyed?).to be_false
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'false if model destroyed.' do
|
148
|
+
@model.destroy
|
149
|
+
expect(@model.destroyed?).to be_true
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'alias deleted? to destroyed?' do
|
153
|
+
expect(@model.deleted?).to be_false
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when restore(class method)' do
|
158
|
+
before :each do
|
159
|
+
@model.destroy
|
160
|
+
|
161
|
+
@model2 = ParanoidModel.create!
|
162
|
+
@model2.destroy
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'with id, restore model.' do
|
166
|
+
expect{
|
167
|
+
ParanoidModel.restore(@model.id)
|
168
|
+
}.to change(ParanoidModel, :count).by(1)
|
169
|
+
|
170
|
+
expect(@model.reload.destroyed?).to be_false
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'with ids, restore models.' do
|
174
|
+
expect{
|
175
|
+
ParanoidModel.restore([@model.id, @model2.id])
|
176
|
+
}.to change(ParanoidModel, :count).by(2)
|
177
|
+
|
178
|
+
expect(@model.reload.destroyed?).to be_false
|
179
|
+
expect(@model2.reload.destroyed?).to be_false
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'when restore(instance method)' do
|
184
|
+
before :each do
|
185
|
+
@model.destroy
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'restore model' do
|
189
|
+
expect{
|
190
|
+
@model.restore!
|
191
|
+
}.to change(ParanoidModel, :count).by(1)
|
192
|
+
|
193
|
+
expect(@model.reload.destroyed?).to be_false
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'call callbacks of restore.' do
|
197
|
+
ParanoidModel.before_restore :before_restore_callback
|
198
|
+
ParanoidModel.after_restore :after_restore_callback
|
199
|
+
ParanoidModel.after_commit :after_commit_callback
|
200
|
+
|
201
|
+
@model.should_receive(:before_restore_callback).once
|
202
|
+
@model.should_receive(:after_restore_callback).once
|
203
|
+
@model.should_receive(:after_commit_callback).once.and_return(true)
|
204
|
+
|
205
|
+
@model.restore!
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'not call callbacks without restore.' do
|
209
|
+
ParanoidModel.before_update :before_update_callback
|
210
|
+
ParanoidModel.before_save :before_save_callback
|
211
|
+
ParanoidModel.validate :validate_callback
|
212
|
+
|
213
|
+
@model.should_receive(:before_update_callback).exactly(0).times
|
214
|
+
@model.should_receive(:before_save_callback).exactly(0).times
|
215
|
+
@model.should_receive(:validate_callback).exactly(0).times
|
216
|
+
|
217
|
+
@model.restore!
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'alias recover to restore!' do
|
221
|
+
expect{
|
222
|
+
@model.restore!
|
223
|
+
}.to change(ParanoidModel, :count).by(1)
|
224
|
+
|
225
|
+
expect(@model.reload.destroyed?).to be_false
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Kakurenbo::SoftDeleteCore::Scopes do
|
4
|
+
create_temp_table(:paranoid_models){ |t| t.datetime :deleted_at }
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
class ParanoidModel < ActiveRecord::Base; end
|
8
|
+
end
|
9
|
+
|
10
|
+
after :each do
|
11
|
+
Object.class_eval{ remove_const :ParanoidModel }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when call scope of' do
|
15
|
+
before :each do
|
16
|
+
@existing_model = ParanoidModel.create!
|
17
|
+
@deleted_model = ParanoidModel.create!(deleted_at: Time.now)
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'default_scope' do
|
21
|
+
it 'show existing model.' do
|
22
|
+
expect(ParanoidModel.find_by(id: @existing_model.id)).not_to be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'hide deleted model.' do
|
26
|
+
expect(ParanoidModel.find_by(id: @deleted_model.id)).to be_nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'only_deleted' do
|
31
|
+
it 'hide existing model.' do
|
32
|
+
expect(ParanoidModel.only_deleted.find_by(id: @existing_model.id)).to be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'show deleted model.' do
|
36
|
+
expect(ParanoidModel.only_deleted.find_by(@deleted_model.id)).not_to be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with_deleted' do
|
41
|
+
it 'show existing model.' do
|
42
|
+
expect(ParanoidModel.with_deleted.find_by(id: @existing_model.id)).not_to be_nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'show deleted model.' do
|
46
|
+
expect(ParanoidModel.with_deleted.find_by(@deleted_model.id)).not_to be_nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'without_deleted' do
|
51
|
+
it 'show existing model.' do
|
52
|
+
expect(ParanoidModel.without_deleted.find_by(id: @existing_model.id)).not_to be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'hide deleted model.' do
|
56
|
+
expect(ParanoidModel.without_deleted.find_by(id: @deleted_model.id)).to be_nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kakurenbo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- alfa-jpn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -119,7 +119,10 @@ files:
|
|
119
119
|
- lib/kakurenbo/soft_delete_core.rb
|
120
120
|
- lib/kakurenbo/version.rb
|
121
121
|
- spec/kakurenbo/mixin_ar_base_spec.rb
|
122
|
-
- spec/kakurenbo/
|
122
|
+
- spec/kakurenbo/soft_delete_cores/associations_spec.rb
|
123
|
+
- spec/kakurenbo/soft_delete_cores/callbacks_spec.rb
|
124
|
+
- spec/kakurenbo/soft_delete_cores/core_spec.rb
|
125
|
+
- spec/kakurenbo/soft_delete_cores/scopes_spec.rb
|
123
126
|
- spec/spec_helper.rb
|
124
127
|
homepage: https://github.com/alfa-jpn/kakurenbo
|
125
128
|
licenses:
|
@@ -148,6 +151,9 @@ summary: provides soft delete. Kakurenbo is a re-implementation of paranoia and
|
|
148
151
|
for Rails4 and 3. implemented a function that other gems are not enough.
|
149
152
|
test_files:
|
150
153
|
- spec/kakurenbo/mixin_ar_base_spec.rb
|
151
|
-
- spec/kakurenbo/
|
154
|
+
- spec/kakurenbo/soft_delete_cores/associations_spec.rb
|
155
|
+
- spec/kakurenbo/soft_delete_cores/callbacks_spec.rb
|
156
|
+
- spec/kakurenbo/soft_delete_cores/core_spec.rb
|
157
|
+
- spec/kakurenbo/soft_delete_cores/scopes_spec.rb
|
152
158
|
- spec/spec_helper.rb
|
153
159
|
has_rdoc:
|
@@ -1,420 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Kakurenbo::MixinARBase do
|
4
|
-
create_temp_table(:paranoid_models){ |t| t.datetime :deleted_at }
|
5
|
-
|
6
|
-
create_temp_table(:parent_models) { |t| t.integer :child_id; t.datetime :deleted_at }
|
7
|
-
create_temp_table(:normal_child_models) { |t| t.integer :parent_model_id }
|
8
|
-
create_temp_table(:paranoid_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
|
9
|
-
create_temp_table(:paranoid_single_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
|
10
|
-
|
11
|
-
context 'when define ParanoidModel' do
|
12
|
-
before :each do
|
13
|
-
class ParanoidModel < ActiveRecord::Base; end
|
14
|
-
end
|
15
|
-
|
16
|
-
after :each do
|
17
|
-
Object.class_eval{ remove_const :ParanoidModel }
|
18
|
-
end
|
19
|
-
|
20
|
-
describe 'Callbacks' do
|
21
|
-
before :each do
|
22
|
-
@callback_model = ParanoidModel.create!
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'before_restore.' do
|
26
|
-
ParanoidModel.before_restore :before_restore_callback
|
27
|
-
@callback_model.should_receive(:before_restore_callback).once
|
28
|
-
@callback_model.run_callbacks(:restore)
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'around_restore.' do
|
32
|
-
ParanoidModel.around_restore :around_restore_callback
|
33
|
-
@callback_model.should_receive(:around_restore_callback).once
|
34
|
-
@callback_model.run_callbacks(:restore)
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'after_restore.' do
|
38
|
-
ParanoidModel.after_restore :after_restore_callback
|
39
|
-
@callback_model.should_receive(:after_restore_callback).once
|
40
|
-
@callback_model.run_callbacks(:restore)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
describe 'Scopes' do
|
46
|
-
before :each do
|
47
|
-
@normal_model = ParanoidModel.create!
|
48
|
-
@deleted_model = ParanoidModel.create!(deleted_at: Time.now)
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'when use default_scope' do
|
52
|
-
it 'show normal model.' do
|
53
|
-
expect(ParanoidModel.find_by(id: @normal_model.id)).not_to be_nil
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'hide deleted model.' do
|
57
|
-
expect(ParanoidModel.find_by(id: @deleted_model.id)).to be_nil
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
context 'when use only_deleted' do
|
62
|
-
it 'show normal model.' do
|
63
|
-
expect(ParanoidModel.only_deleted.find_by(id: @normal_model.id)).to be_nil
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'show deleted model.' do
|
67
|
-
expect(ParanoidModel.only_deleted.find_by(@deleted_model.id)).not_to be_nil
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'when use with_deleted' do
|
72
|
-
it 'show normal model.' do
|
73
|
-
expect(ParanoidModel.with_deleted.find_by(id: @normal_model.id)).not_to be_nil
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'show deleted model.' do
|
77
|
-
expect(ParanoidModel.with_deleted.find_by(@deleted_model.id)).not_to be_nil
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
context 'when use without_deleted' do
|
82
|
-
it 'show normal model.' do
|
83
|
-
expect(ParanoidModel.without_deleted.find_by(id: @normal_model.id)).not_to be_nil
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'hide deleted model.' do
|
87
|
-
expect(ParanoidModel.without_deleted.find_by(id: @deleted_model.id)).to be_nil
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
|
93
|
-
describe 'Core' do
|
94
|
-
before :each do
|
95
|
-
@model = ParanoidModel.create!
|
96
|
-
end
|
97
|
-
|
98
|
-
context 'when delete' do
|
99
|
-
it 'soft-delete model.' do
|
100
|
-
expect{
|
101
|
-
@model.delete
|
102
|
-
}.to change(ParanoidModel, :count).by(-1)
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'not hard-delete model.' do
|
106
|
-
expect{
|
107
|
-
@model.delete
|
108
|
-
}.to change{
|
109
|
-
ParanoidModel.all.with_deleted.count
|
110
|
-
}.by(0)
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'call callbacks nothing.' do
|
114
|
-
ParanoidModel.before_destroy :before_destroy_callback
|
115
|
-
ParanoidModel.after_destroy :after_destroy_callback
|
116
|
-
ParanoidModel.after_commit :after_commit_callback
|
117
|
-
|
118
|
-
@model.should_receive(:before_destroy_callback).exactly(0).times
|
119
|
-
@model.should_receive(:after_destroy_callback).exactly(0).times
|
120
|
-
@model.should_receive(:after_commit_callback).exactly(0).times
|
121
|
-
|
122
|
-
@model.delete
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'not call callbacks other.' do
|
126
|
-
ParanoidModel.before_update :before_update_callback
|
127
|
-
ParanoidModel.before_save :before_save_callback
|
128
|
-
ParanoidModel.validate :validate_callback
|
129
|
-
|
130
|
-
@model.should_receive(:before_update_callback).exactly(0).times
|
131
|
-
@model.should_receive(:before_save_callback).exactly(0).times
|
132
|
-
@model.should_receive(:validate_callback).exactly(0).times
|
133
|
-
|
134
|
-
@model.delete
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
context 'when delete!' do
|
139
|
-
it 'hard-delete model.' do
|
140
|
-
expect{
|
141
|
-
@model.delete!
|
142
|
-
}.to change{
|
143
|
-
ParanoidModel.all.with_deleted.count
|
144
|
-
}.by(-1)
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
context 'when destroy' do
|
149
|
-
it 'soft-delete model.' do
|
150
|
-
expect{
|
151
|
-
@model.destroy
|
152
|
-
}.to change(ParanoidModel, :count).by(-1)
|
153
|
-
end
|
154
|
-
|
155
|
-
it 'not hard-delete model.' do
|
156
|
-
expect{
|
157
|
-
@model.destroy
|
158
|
-
}.to change{
|
159
|
-
ParanoidModel.all.with_deleted.count
|
160
|
-
}.by(0)
|
161
|
-
end
|
162
|
-
|
163
|
-
it 'call callbacks of destroy.' do
|
164
|
-
ParanoidModel.before_destroy :before_destroy_callback
|
165
|
-
ParanoidModel.after_destroy :after_destroy_callback
|
166
|
-
ParanoidModel.after_commit :after_commit_callback
|
167
|
-
|
168
|
-
@model.should_receive(:before_destroy_callback).once
|
169
|
-
@model.should_receive(:after_destroy_callback).once
|
170
|
-
@model.should_receive(:after_commit_callback).once.and_return(true)
|
171
|
-
|
172
|
-
@model.destroy
|
173
|
-
end
|
174
|
-
|
175
|
-
it 'not call callbacks without destroy.' do
|
176
|
-
ParanoidModel.before_update :before_update_callback
|
177
|
-
ParanoidModel.before_save :before_save_callback
|
178
|
-
ParanoidModel.validate :validate_callback
|
179
|
-
|
180
|
-
@model.should_receive(:before_update_callback).exactly(0).times
|
181
|
-
@model.should_receive(:before_save_callback).exactly(0).times
|
182
|
-
@model.should_receive(:validate_callback).exactly(0).times
|
183
|
-
|
184
|
-
@model.destroy
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
context 'when destroy!' do
|
189
|
-
it 'hard-delete model.' do
|
190
|
-
expect{
|
191
|
-
@model.destroy!
|
192
|
-
}.to change{
|
193
|
-
ParanoidModel.all.with_deleted.count
|
194
|
-
}.by(-1)
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
context 'when destroyed?' do
|
199
|
-
it 'false if model not destroyed.' do
|
200
|
-
expect(@model.destroyed?).to be_false
|
201
|
-
end
|
202
|
-
|
203
|
-
it 'false if model destroyed.' do
|
204
|
-
@model.destroy
|
205
|
-
expect(@model.destroyed?).to be_true
|
206
|
-
end
|
207
|
-
|
208
|
-
it 'alias_method deleted? to destroyed?' do
|
209
|
-
expect(@model.deleted?).to be_false
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
context 'when restore.(class method)' do
|
214
|
-
before :each do
|
215
|
-
@model.destroy
|
216
|
-
end
|
217
|
-
|
218
|
-
it 'with id restore of instance method.' do
|
219
|
-
expect{
|
220
|
-
ParanoidModel.restore(@model.id)
|
221
|
-
}.to change(ParanoidModel, :count).by(1)
|
222
|
-
|
223
|
-
expect(@model.reload.destroyed?).to be_false
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'with ids restore of instance method.' do
|
227
|
-
@model2 = ParanoidModel.create!
|
228
|
-
@model2.destroy
|
229
|
-
|
230
|
-
expect{
|
231
|
-
ParanoidModel.restore([@model.id, @model2.id])
|
232
|
-
}.to change(ParanoidModel, :count).by(2)
|
233
|
-
|
234
|
-
expect(@model.reload.destroyed?).to be_false
|
235
|
-
expect(@model2.reload.destroyed?).to be_false
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
context 'when restore.(instance method)' do
|
240
|
-
before :each do
|
241
|
-
@model.destroy
|
242
|
-
end
|
243
|
-
|
244
|
-
it 'restore model' do
|
245
|
-
expect{
|
246
|
-
@model.restore!
|
247
|
-
}.to change(ParanoidModel, :count).by(1)
|
248
|
-
|
249
|
-
expect(@model.reload.destroyed?).to be_false
|
250
|
-
end
|
251
|
-
|
252
|
-
it 'call callbacks of restore.' do
|
253
|
-
ParanoidModel.before_restore :before_restore_callback
|
254
|
-
ParanoidModel.after_restore :after_restore_callback
|
255
|
-
ParanoidModel.after_commit :after_commit_callback
|
256
|
-
|
257
|
-
@model.should_receive(:before_restore_callback).once
|
258
|
-
@model.should_receive(:after_restore_callback).once
|
259
|
-
@model.should_receive(:after_commit_callback).once.and_return(true)
|
260
|
-
|
261
|
-
@model.restore!
|
262
|
-
end
|
263
|
-
|
264
|
-
it 'not call callbacks without restore.' do
|
265
|
-
ParanoidModel.before_update :before_update_callback
|
266
|
-
ParanoidModel.before_save :before_save_callback
|
267
|
-
ParanoidModel.validate :validate_callback
|
268
|
-
|
269
|
-
@model.should_receive(:before_update_callback).exactly(0).times
|
270
|
-
@model.should_receive(:before_save_callback).exactly(0).times
|
271
|
-
@model.should_receive(:validate_callback).exactly(0).times
|
272
|
-
|
273
|
-
@model.restore!
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
|
280
|
-
context 'when define relation model' do
|
281
|
-
before :all do
|
282
|
-
class NormalChildModel < ActiveRecord::Base; end
|
283
|
-
class ParanoidChildModel < ActiveRecord::Base; end
|
284
|
-
class ParanoidSingleChildModel < ActiveRecord::Base; end
|
285
|
-
class ParentModel < ActiveRecord::Base
|
286
|
-
has_many :normal_child_models, :dependent => :destroy
|
287
|
-
has_many :paranoid_child_models, :dependent => :destroy
|
288
|
-
|
289
|
-
has_one :paranoid_single_child_model, :dependent => :destroy
|
290
|
-
belongs_to :child, :class_name => :ParanoidSingleChildModel, :dependent => :destroy
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
describe 'NormalChildModel' do
|
295
|
-
before :each do
|
296
|
-
@parent = ParentModel.create!
|
297
|
-
@first = @parent.normal_child_models.create!
|
298
|
-
@second = @parent.normal_child_models.create!
|
299
|
-
end
|
300
|
-
|
301
|
-
context 'when parent was destroyed' do
|
302
|
-
it 'remove normal_child_models' do
|
303
|
-
expect{@parent.destroy}.to change(NormalChildModel, :count).by(-2)
|
304
|
-
expect(@first.destroyed?).to be_true
|
305
|
-
expect(@second.destroyed?).to be_true
|
306
|
-
end
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
|
-
describe 'ParanoidChildModel' do
|
311
|
-
before :each do
|
312
|
-
@parent = ParentModel.create!
|
313
|
-
@first = @parent.paranoid_child_models.create!
|
314
|
-
@second = @parent.paranoid_child_models.create!
|
315
|
-
@third = @parent.paranoid_child_models.create!
|
316
|
-
end
|
317
|
-
|
318
|
-
context 'when parent was destroyed' do
|
319
|
-
it 'remove normal_child_models' do
|
320
|
-
expect{@parent.destroy}.to change(ParanoidChildModel, :count).by(-3)
|
321
|
-
expect(@first.reload.destroyed?).to be_true
|
322
|
-
expect(@second.reload.destroyed?).to be_true
|
323
|
-
expect(@third.reload.destroyed?).to be_true
|
324
|
-
end
|
325
|
-
|
326
|
-
it 'restore with normal_child_models' do
|
327
|
-
@parent.destroy
|
328
|
-
expect{@parent.restore!}.to change(ParanoidChildModel, :count).by(3)
|
329
|
-
expect(@first.reload.destroyed?).to be_false
|
330
|
-
expect(@second.reload.destroyed?).to be_false
|
331
|
-
expect(@third.reload.destroyed?).to be_false
|
332
|
-
end
|
333
|
-
|
334
|
-
it 'not restore model that was deleted before parent was deleted.' do
|
335
|
-
# Delete before parent was deleted.
|
336
|
-
delete_at = 1.second.ago
|
337
|
-
Time.stub(:now).and_return(delete_at)
|
338
|
-
@first.destroy
|
339
|
-
|
340
|
-
# Delete after first_child was deleted.
|
341
|
-
Time.unstub(:now)
|
342
|
-
@parent.destroy
|
343
|
-
|
344
|
-
expect{@parent.restore!}.to change(ParanoidChildModel, :count).by(2)
|
345
|
-
expect(@first.reload.destroyed?).to be_true
|
346
|
-
expect(@second.reload.destroyed?).to be_false
|
347
|
-
expect(@third.reload.destroyed?).to be_false
|
348
|
-
end
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
|
-
describe 'ParanoidSingleChildModel' do
|
353
|
-
before :each do
|
354
|
-
@parent = ParentModel.create!
|
355
|
-
@first = ParanoidSingleChildModel.create!(parent_model_id: @parent.id)
|
356
|
-
end
|
357
|
-
|
358
|
-
context 'when parent was destroyed' do
|
359
|
-
it 'remove normal_child_models' do
|
360
|
-
expect{@parent.destroy}.to change(ParanoidSingleChildModel, :count).by(-1)
|
361
|
-
expect(@first.reload.destroyed?).to be_true
|
362
|
-
end
|
363
|
-
|
364
|
-
it 'restore with normal_child_models' do
|
365
|
-
@parent.destroy
|
366
|
-
expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(1)
|
367
|
-
expect(@first.reload.destroyed?).to be_false
|
368
|
-
end
|
369
|
-
|
370
|
-
it 'not restore model that was deleted before parent was deleted.' do
|
371
|
-
# Delete before parent was deleted.
|
372
|
-
delete_at = 1.second.ago
|
373
|
-
Time.stub(:now).and_return(delete_at)
|
374
|
-
@first.destroy
|
375
|
-
|
376
|
-
# Delete after first_child was deleted.
|
377
|
-
Time.unstub(:now)
|
378
|
-
@parent.destroy
|
379
|
-
|
380
|
-
expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(0)
|
381
|
-
expect(@first.reload.destroyed?).to be_true
|
382
|
-
end
|
383
|
-
end
|
384
|
-
end
|
385
|
-
|
386
|
-
describe 'ParanoidSingleChildModel' do
|
387
|
-
before :each do
|
388
|
-
@first = ParanoidSingleChildModel.create!
|
389
|
-
@parent = ParentModel.create!(child_id: @first.id)
|
390
|
-
end
|
391
|
-
|
392
|
-
context 'when parent was destroyed' do
|
393
|
-
it 'remove normal_child_models' do
|
394
|
-
expect{@parent.destroy}.to change(ParanoidSingleChildModel, :count).by(-1)
|
395
|
-
expect(@first.reload.destroyed?).to be_true
|
396
|
-
end
|
397
|
-
|
398
|
-
it 'restore with normal_child_models' do
|
399
|
-
@parent.destroy
|
400
|
-
expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(1)
|
401
|
-
expect(@first.reload.destroyed?).to be_false
|
402
|
-
end
|
403
|
-
|
404
|
-
it 'not restore model that was deleted before parent was deleted.' do
|
405
|
-
# Delete before parent was deleted.
|
406
|
-
delete_at = 1.second.ago
|
407
|
-
Time.stub(:now).and_return(delete_at)
|
408
|
-
@first.destroy
|
409
|
-
|
410
|
-
# Delete after first_child was deleted.
|
411
|
-
Time.unstub(:now)
|
412
|
-
@parent.destroy
|
413
|
-
|
414
|
-
expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(0)
|
415
|
-
expect(@first.reload.destroyed?).to be_true
|
416
|
-
end
|
417
|
-
end
|
418
|
-
end
|
419
|
-
end
|
420
|
-
end
|