permanent_records 3.2.0 → 3.3.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 +5 -2
- data/.gitignore +3 -0
- data/.travis.yml +9 -0
- data/CONTRIBUTORS.md +12 -0
- data/README.markdown +8 -8
- data/VERSION +1 -1
- data/lib/permanent_records.rb +13 -9
- data/permanent_records.gemspec +2 -25
- data/spec/permanent_records_spec.rb +90 -9
- metadata +7 -3
checksums.yaml
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 04a19ebb7eaed9a5f5269e95e0655b1c3beb7d59
|
|
4
|
+
data.tar.gz: 24b041c8d21fb99043f5593eed109a5d372ed2dd
|
|
2
5
|
SHA512:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 06d0fed27670e3a7f4342af120ef8464a5e560afdce3c357129bfcffeb7e5ec423405afcea8d75e880d2c389e605152a27dfc9755f1d10a5f30e713e51fe3b72
|
|
7
|
+
data.tar.gz: 5e4c127d4485362f7ccf12ce5fba120109dbe5201585b15603086985e98b7f209d8abb7e182d649b80d04670333cc3d1c8dfef561ab0eeeff9de2ea20779d079
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CONTRIBUTORS.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Folks who gave their time and effort and didn't have to:
|
|
2
|
+
|
|
3
|
+
* [David Sulc](https://github.com/davidsulc)
|
|
4
|
+
* [Joe Nelson](https://github.com/begriffs)
|
|
5
|
+
* [Trond Arve Nordheim](https://github.com/tanordheim)
|
|
6
|
+
* [Josh Teneycke](https://github.com/jteneycke)
|
|
7
|
+
* [Maximilian Herold](https://github.com/mherold)
|
|
8
|
+
|
|
9
|
+
To join this list just open a GH issue with some code you'd like to
|
|
10
|
+
change in this project. New features are fine, bug fixes are better. No
|
|
11
|
+
experience or credentials necessary to begin contributing - if you can
|
|
12
|
+
read this you're welcome to join.
|
data/README.markdown
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# PermanentRecords (Rails 3+)
|
|
1
|
+
# PermanentRecords (Rails 3.1+)
|
|
2
2
|
|
|
3
3
|
[http://github.com/JackDanger/permanent_records/](http://github.com/JackDanger/permanent_records/)
|
|
4
4
|
|
|
@@ -8,12 +8,12 @@ Any model that you've given a "deleted_at" datetime column will have that column
|
|
|
8
8
|
## What methods does it give me?
|
|
9
9
|
|
|
10
10
|
```ruby
|
|
11
|
-
User.find(3).destroy # Sets the 'deleted_at' attribute to Time.now
|
|
11
|
+
User.find(3).destroy # Sets the 'deleted_at' attribute to Time.now
|
|
12
12
|
# and returns a frozen record.
|
|
13
|
-
|
|
14
|
-
User.find(3).destroy(:force) # Executes the real destroy method, the record
|
|
13
|
+
|
|
14
|
+
User.find(3).destroy(:force) # Executes the real destroy method, the record
|
|
15
15
|
# will be removed from the database.
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
User.destroy_all # Soft-deletes all User records.
|
|
18
18
|
|
|
19
19
|
User.delete_all # bye bye everything (no soft-deleting here)
|
|
@@ -53,7 +53,7 @@ end
|
|
|
53
53
|
|
|
54
54
|
User.find(3).destroy # All the comments are destroyed as well.
|
|
55
55
|
|
|
56
|
-
User.find(3).revive # All the comments that were just destroyed
|
|
56
|
+
User.find(3).revive # All the comments that were just destroyed
|
|
57
57
|
# are now back in pristine condition.
|
|
58
58
|
```
|
|
59
59
|
|
|
@@ -75,7 +75,7 @@ end
|
|
|
75
75
|
|
|
76
76
|
## Is Everything Automated?
|
|
77
77
|
|
|
78
|
-
Yes. You don't have to change ANY of your code to get permanent archiving of all your data with this gem.
|
|
78
|
+
Yes. You don't have to change ANY of your code to get permanent archiving of all your data with this gem.
|
|
79
79
|
When you call `destroy` on any record (or `destroy_all` on a class or association) your records will
|
|
80
80
|
all have a deleted_at timestamp set on them.
|
|
81
81
|
|
|
@@ -88,4 +88,4 @@ value that works for you.
|
|
|
88
88
|
|
|
89
89
|
Patches welcome, forks celebrated.
|
|
90
90
|
|
|
91
|
-
Copyright
|
|
91
|
+
Copyright 2015 Jack Danger Canty @ [https://jdanger.com](https://jdanger.com) released under the MIT license
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.3.0
|
data/lib/permanent_records.rb
CHANGED
|
@@ -33,15 +33,20 @@ module PermanentRecords
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def revive(validate = nil)
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
with_transaction_returning_status do
|
|
37
|
+
run_callbacks(:revive) { set_deleted_at(nil, validate) }
|
|
38
|
+
self
|
|
39
|
+
end
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
def destroy(force = nil)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
with_transaction_returning_status do
|
|
44
|
+
if !is_permanent? || PermanentRecords.should_force_destroy?(force)
|
|
45
|
+
permanently_delete_records_after { super() }
|
|
46
|
+
else
|
|
47
|
+
destroy_with_permanent_records force
|
|
48
|
+
end
|
|
43
49
|
end
|
|
44
|
-
destroy_with_permanent_records force
|
|
45
50
|
end
|
|
46
51
|
|
|
47
52
|
private
|
|
@@ -60,16 +65,15 @@ module PermanentRecords
|
|
|
60
65
|
record.save!
|
|
61
66
|
end
|
|
62
67
|
if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) < ::Gem::Version.new('4.2.0')
|
|
63
|
-
@attributes
|
|
68
|
+
@attributes = record.attributes
|
|
69
|
+
@attributes_cache = record.attributes.except(record.class.serialized_attributes.keys)
|
|
64
70
|
# workaround for active_record >= 3.2.0: re-wrap values of serialized attributes
|
|
65
71
|
# (record.attributes returns the plain values but in the instance variables they are expected to be wrapped)
|
|
66
72
|
if defined?(::ActiveRecord::AttributeMethods::Serialization::Attribute)
|
|
67
73
|
serialized_attribute_class = ::ActiveRecord::AttributeMethods::Serialization::Attribute
|
|
68
74
|
self.class.serialized_attributes.each do |key, coder|
|
|
69
75
|
if @attributes.key?(key)
|
|
70
|
-
|
|
71
|
-
@attributes[key] = attr
|
|
72
|
-
@attributes_cache[key] = attr
|
|
76
|
+
@attributes[key] = serialized_attribute_class.new(coder, @attributes[key], :unserialized)
|
|
73
77
|
end
|
|
74
78
|
end
|
|
75
79
|
end
|
data/permanent_records.gemspec
CHANGED
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
|
11
11
|
s.license = 'MIT'
|
|
12
12
|
|
|
13
13
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
14
|
-
s.authors = ["Jack Danger Canty", "David Sulc", "Joe Nelson", "Trond Arve Nordheim", "Josh Teneycke"]
|
|
14
|
+
s.authors = ["Jack Danger Canty", "David Sulc", "Joe Nelson", "Trond Arve Nordheim", "Josh Teneycke", "Maximilian Herold"]
|
|
15
15
|
s.date = Date.today.to_s
|
|
16
16
|
s.description = "Never Lose Data. Rather than deleting rows this sets Record#deleted_at and gives you all the scopes you need to work with your data."
|
|
17
17
|
s.email = "gems@6brand.com"
|
|
@@ -19,30 +19,7 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
"LICENSE",
|
|
20
20
|
"README.markdown"
|
|
21
21
|
]
|
|
22
|
-
s.files =
|
|
23
|
-
".document",
|
|
24
|
-
"Gemfile",
|
|
25
|
-
"LICENSE",
|
|
26
|
-
"README.markdown",
|
|
27
|
-
"Rakefile",
|
|
28
|
-
"VERSION",
|
|
29
|
-
"lib/permanent_records.rb",
|
|
30
|
-
"permanent_records.gemspec",
|
|
31
|
-
"spec/spec_helper.rb",
|
|
32
|
-
"spec/permanent_records_spec.rb",
|
|
33
|
-
"spec/support/comment.rb",
|
|
34
|
-
"spec/support/database.yml",
|
|
35
|
-
"spec/support/difficulty.rb",
|
|
36
|
-
"spec/support/dirt.rb",
|
|
37
|
-
"spec/support/earthworm.rb",
|
|
38
|
-
"spec/support/hole.rb",
|
|
39
|
-
"spec/support/kitty.rb",
|
|
40
|
-
"spec/support/location.rb",
|
|
41
|
-
"spec/support/mole.rb",
|
|
42
|
-
"spec/support/muskrat.rb",
|
|
43
|
-
"spec/support/schema.rb",
|
|
44
|
-
"spec/support/unused_model.rb"
|
|
45
|
-
]
|
|
22
|
+
s.files = `git ls-files`.split($\)
|
|
46
23
|
s.homepage = "https://github.com/JackDanger/permanent_records"
|
|
47
24
|
s.require_paths = ["lib"]
|
|
48
25
|
s.rubygems_version = "1.8.17"
|
|
@@ -5,7 +5,7 @@ describe PermanentRecords do
|
|
|
5
5
|
let!(:frozen_moment) { Time.now }
|
|
6
6
|
let!(:dirt) { Dirt.create! }
|
|
7
7
|
let!(:earthworm) { dirt.create_earthworm }
|
|
8
|
-
let!(:hole) { dirt.create_hole
|
|
8
|
+
let!(:hole) { dirt.create_hole(:options => {}) }
|
|
9
9
|
let!(:muskrat) { hole.muskrats.create! }
|
|
10
10
|
let!(:mole) { hole.moles.create! }
|
|
11
11
|
let!(:location) { hole.create_location }
|
|
@@ -38,8 +38,8 @@ describe PermanentRecords do
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it 'handles serialized attributes correctly' do
|
|
41
|
-
expect
|
|
42
|
-
expect
|
|
41
|
+
expect(subject.options).to eq({})
|
|
42
|
+
expect(subject.size).to be_nil if record.respond_to?(:size)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
context 'with force argument set to truthy' do
|
|
@@ -77,7 +77,6 @@ describe PermanentRecords do
|
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
|
|
81
80
|
context 'when model has no deleted_at column' do
|
|
82
81
|
let(:record) { kitty }
|
|
83
82
|
|
|
@@ -100,10 +99,25 @@ describe PermanentRecords do
|
|
|
100
99
|
it 'marks records as deleted' do
|
|
101
100
|
subject.muskrats.each {|m| m.should be_deleted }
|
|
102
101
|
end
|
|
102
|
+
|
|
103
|
+
context 'when error occurs' do
|
|
104
|
+
before { Hole.any_instance.stub(:valid?).and_return(false) }
|
|
105
|
+
it 'does not mark records as deleted' do
|
|
106
|
+
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
|
|
107
|
+
expect(record.muskrats.not_deleted.count).to eq(1)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
103
111
|
context 'with force delete' do
|
|
104
112
|
let(:should_force) { :force }
|
|
105
113
|
it('') { expect { subject }.to change { Muskrat.count }.by(-1) }
|
|
106
114
|
it('') { expect { subject }.to change { Comment.count }.by(-2) }
|
|
115
|
+
|
|
116
|
+
context 'when error occurs' do
|
|
117
|
+
before { Difficulty.any_instance.stub(:destroy).and_return(false) }
|
|
118
|
+
it('') { expect { subject }.not_to change { Muskrat.count } }
|
|
119
|
+
it('') { expect { subject }.not_to change { Comment.count } }
|
|
120
|
+
end
|
|
107
121
|
end
|
|
108
122
|
end
|
|
109
123
|
|
|
@@ -111,18 +125,59 @@ describe PermanentRecords do
|
|
|
111
125
|
it 'marks records as deleted' do
|
|
112
126
|
subject.location.should be_deleted
|
|
113
127
|
end
|
|
128
|
+
|
|
129
|
+
context 'when error occurs' do
|
|
130
|
+
before { Hole.any_instance.stub(:valid?).and_return(false) }
|
|
131
|
+
it('does not mark records as deleted') do
|
|
132
|
+
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
|
|
133
|
+
expect(record.location(true)).not_to be_deleted
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
114
137
|
context 'with force delete' do
|
|
115
138
|
let(:should_force) { :force }
|
|
116
139
|
it('') { expect { subject }.to change { Muskrat.count }.by(-1) }
|
|
117
140
|
it('') { expect { subject }.to change { Location.count }.by(-1) }
|
|
141
|
+
|
|
142
|
+
context 'when error occurs' do
|
|
143
|
+
before { Difficulty.any_instance.stub(:destroy).and_return(false) }
|
|
144
|
+
it('') { expect { subject }.not_to change { Muskrat.count } }
|
|
145
|
+
it('') { expect { subject }.not_to change { Location.count } }
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
context 'with belongs_to cardinality' do
|
|
151
|
+
it 'marks records as deleted' do
|
|
152
|
+
subject.dirt.should be_deleted
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
context 'when error occurs' do
|
|
156
|
+
before { Hole.any_instance.stub(:valid?).and_return(false) }
|
|
157
|
+
it 'does not mark records as deleted' do
|
|
158
|
+
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
|
|
159
|
+
expect(record.dirt(true)).not_to be_deleted
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
context 'with force delete' do
|
|
164
|
+
let(:should_force) { :force }
|
|
165
|
+
it('') { expect { subject }.to change { Dirt.count }.by(-1) }
|
|
166
|
+
|
|
167
|
+
context 'when error occurs' do
|
|
168
|
+
before { Difficulty.any_instance.stub(:destroy).and_return(false) }
|
|
169
|
+
it('') { expect { subject }.not_to change { Dirt.count } }
|
|
170
|
+
end
|
|
118
171
|
end
|
|
119
172
|
end
|
|
120
173
|
end
|
|
174
|
+
|
|
121
175
|
context 'that are non-permanent' do
|
|
122
176
|
it 'removes them' do
|
|
123
177
|
expect { subject }.to change { Mole.count }.by(-1)
|
|
124
178
|
end
|
|
125
179
|
end
|
|
180
|
+
|
|
126
181
|
context 'as default scope' do
|
|
127
182
|
let(:load_comments) { Comment.unscoped.where(:hole_id => subject.id) }
|
|
128
183
|
context 'with :has_many cardinality' do
|
|
@@ -131,11 +186,7 @@ describe PermanentRecords do
|
|
|
131
186
|
}
|
|
132
187
|
it 'deletes them' do
|
|
133
188
|
load_comments.all?(&:deleted?).should be_true
|
|
134
|
-
|
|
135
|
-
# (in versions with non-broken default scope)
|
|
136
|
-
if ActiveRecord::VERSION::STRING > '3.0.0'
|
|
137
|
-
subject.comments.should be_blank
|
|
138
|
-
end
|
|
189
|
+
subject.comments.should be_blank
|
|
139
190
|
end
|
|
140
191
|
end
|
|
141
192
|
context 'with :has_one cardinality' do
|
|
@@ -205,19 +256,49 @@ describe PermanentRecords do
|
|
|
205
256
|
it 'revives them' do
|
|
206
257
|
subject.muskrats.each {|m| m.should_not be_deleted }
|
|
207
258
|
end
|
|
259
|
+
context 'when error occurs' do
|
|
260
|
+
before { Hole.any_instance.stub(:valid?).and_return(false) }
|
|
261
|
+
it 'does not revive them' do
|
|
262
|
+
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
|
|
263
|
+
expect(record.muskrats.deleted.count).to eq(1)
|
|
264
|
+
end
|
|
265
|
+
end
|
|
208
266
|
end
|
|
209
267
|
|
|
210
268
|
context 'with has_one cardinality' do
|
|
211
269
|
it 'revives them' do
|
|
212
270
|
subject.location.should_not be_deleted
|
|
213
271
|
end
|
|
272
|
+
context 'when error occurs' do
|
|
273
|
+
before { Hole.any_instance.stub(:valid?).and_return(false) }
|
|
274
|
+
it('does not mark records as deleted') do
|
|
275
|
+
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
|
|
276
|
+
expect(record.location(true)).to be_deleted
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
context 'with belongs_to cardinality' do
|
|
282
|
+
it 'revives them' do
|
|
283
|
+
subject.dirt.should_not be_deleted
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
context 'when error occurs' do
|
|
287
|
+
before { Hole.any_instance.stub(:valid?).and_return(false) }
|
|
288
|
+
it 'does not revive them' do
|
|
289
|
+
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
|
|
290
|
+
expect(record.dirt(true)).to be_deleted
|
|
291
|
+
end
|
|
292
|
+
end
|
|
214
293
|
end
|
|
215
294
|
end
|
|
295
|
+
|
|
216
296
|
context 'that are non-permanent' do
|
|
217
297
|
it 'cannot revive them' do
|
|
218
298
|
expect { subject }.to_not change { Mole.count }
|
|
219
299
|
end
|
|
220
300
|
end
|
|
301
|
+
|
|
221
302
|
context 'as default scope' do
|
|
222
303
|
context 'with :has_many cardinality' do
|
|
223
304
|
its('comments.size') { should == 2 }
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: permanent_records
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jack Danger Canty
|
|
@@ -9,10 +9,11 @@ authors:
|
|
|
9
9
|
- Joe Nelson
|
|
10
10
|
- Trond Arve Nordheim
|
|
11
11
|
- Josh Teneycke
|
|
12
|
+
- Maximilian Herold
|
|
12
13
|
autorequire:
|
|
13
14
|
bindir: bin
|
|
14
15
|
cert_chain: []
|
|
15
|
-
date: 2015-
|
|
16
|
+
date: 2015-03-10 00:00:00.000000000 Z
|
|
16
17
|
dependencies:
|
|
17
18
|
- !ruby/object:Gem::Dependency
|
|
18
19
|
name: activerecord
|
|
@@ -52,6 +53,9 @@ extra_rdoc_files:
|
|
|
52
53
|
- README.markdown
|
|
53
54
|
files:
|
|
54
55
|
- ".document"
|
|
56
|
+
- ".gitignore"
|
|
57
|
+
- ".travis.yml"
|
|
58
|
+
- CONTRIBUTORS.md
|
|
55
59
|
- Gemfile
|
|
56
60
|
- LICENSE
|
|
57
61
|
- README.markdown
|
|
@@ -93,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
93
97
|
version: '0'
|
|
94
98
|
requirements: []
|
|
95
99
|
rubyforge_project:
|
|
96
|
-
rubygems_version: 2.4.
|
|
100
|
+
rubygems_version: 2.4.5
|
|
97
101
|
signing_key:
|
|
98
102
|
specification_version: 3
|
|
99
103
|
summary: Soft-delete your ActiveRecord records
|