kakurenbo 0.1.1 → 0.1.2

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
  SHA1:
3
- metadata.gz: 346d73c09028575300edf7ae7d3f5e3e67eb4a26
4
- data.tar.gz: 29a988182dbcf85583edbe4ce740d15bc736c0ac
3
+ metadata.gz: 1db2fcbe670f950ac46f450c5365921042ec298b
4
+ data.tar.gz: b52de24c10f252966d25f629b86679142fcb0024
5
5
  SHA512:
6
- metadata.gz: bb22422cb2a04879d74e6387b2ac481678813e7f621a37961b35a452d434194f123fa4c64a748bd22de44a18543c04d11a035891dfdb243228e1e156612163f8
7
- data.tar.gz: f6013d0b2a5373f3df8c17b5cd3d9783fd003fe1bde2162b3c04ebe3d45acf86815e28be39ac9b722307f6257f4624cb524d35297cb1001c749630914e0b0e0b
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 :delete!, :delete
35
- alias_method :destroy!, :destroy
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
- # Restore models.
16
+ # Destroy model(s).
16
17
  #
17
- # @param id [Array or Integer] id or ids.
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
- only_deleted.where(:id => id).each{|m| m.restore!(options)}
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
- options.reverse_merge!(
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
- resource = send(association.name)
106
- next if resource.nil?
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
- resource.each &block
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
@@ -1,3 +1,3 @@
1
1
  module Kakurenbo
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -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.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-01-27 00:00:00.000000000 Z
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/soft_delete_core_spec.rb
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/soft_delete_core_spec.rb
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