permanent_records 3.3.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTORS.md +1 -0
- data/Gemfile +1 -14
- data/{README.markdown → README.md} +9 -1
- data/VERSION +1 -1
- data/lib/permanent_records.rb +1 -1
- data/permanent_records.gemspec +15 -28
- metadata +76 -34
- data/spec/permanent_records_spec.rb +0 -348
- data/spec/spec_helper.rb +0 -52
- data/spec/support/comment.rb +0 -5
- data/spec/support/database.yml +0 -16
- data/spec/support/difficulty.rb +0 -9
- data/spec/support/dirt.rb +0 -4
- data/spec/support/earthworm.rb +0 -11
- data/spec/support/hole.rb +0 -17
- data/spec/support/kitty.rb +0 -2
- data/spec/support/location.rb +0 -5
- data/spec/support/mole.rb +0 -3
- data/spec/support/muskrat.rb +0 -3
- data/spec/support/schema.rb +0 -59
- data/spec/support/unused_model.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00dfe5b900619ccf63e002edffdddf61bbc68f17
|
4
|
+
data.tar.gz: 652d7bb27018d1d20ad8ab180a675576d2f3ee91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab92380c3dad28c96cc3eb169014dde29cb3e704856546bc8a1bf4b0f3d748be5260f060ba443ebebacbc132ba30c3983b400e3bad0f2b3bed8e9f49a63ae456
|
7
|
+
data.tar.gz: 0738352d25e8da93be2a76f95ddfa245ec4432e3ff5608eecc1d2a5c071dc94dc5ae56851325388af653b71574c6f146b36e57cd48f5889f94687767e88f069b
|
data/CONTRIBUTORS.md
CHANGED
@@ -5,6 +5,7 @@ Folks who gave their time and effort and didn't have to:
|
|
5
5
|
* [Trond Arve Nordheim](https://github.com/tanordheim)
|
6
6
|
* [Josh Teneycke](https://github.com/jteneycke)
|
7
7
|
* [Maximilian Herold](https://github.com/mherold)
|
8
|
+
* [Hugh Evans](https://github.com/hughevans)
|
8
9
|
|
9
10
|
To join this list just open a GH issue with some code you'd like to
|
10
11
|
change in this project. New features are fine, bug fixes are better. No
|
data/Gemfile
CHANGED
@@ -1,16 +1,3 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
|
-
ver = ver.dup.chomp if ver
|
5
|
-
|
6
|
-
gem 'activerecord', ver
|
7
|
-
gem 'activesupport', ver
|
8
|
-
|
9
|
-
group :test do
|
10
|
-
gem 'rake'
|
11
|
-
gem 'sqlite3'
|
12
|
-
gem 'pry'
|
13
|
-
gem 'awesome_print'
|
14
|
-
gem 'database_cleaner'
|
15
|
-
gem 'rspec', '~> 2.14.1'
|
16
|
-
end
|
3
|
+
gemspec
|
@@ -9,7 +9,8 @@ Any model that you've given a "deleted_at" datetime column will have that column
|
|
9
9
|
|
10
10
|
```ruby
|
11
11
|
User.find(3).destroy # Sets the 'deleted_at' attribute to Time.now
|
12
|
-
# and returns a frozen record.
|
12
|
+
# and returns a frozen record. If halted by a
|
13
|
+
# before_destroy callback it returns false instead
|
13
14
|
|
14
15
|
User.find(3).destroy(:force) # Executes the real destroy method, the record
|
15
16
|
# will be removed from the database.
|
@@ -79,6 +80,13 @@ Yes. You don't have to change ANY of your code to get permanent archiving of all
|
|
79
80
|
When you call `destroy` on any record (or `destroy_all` on a class or association) your records will
|
80
81
|
all have a deleted_at timestamp set on them.
|
81
82
|
|
83
|
+
## Upgrading from 3.x
|
84
|
+
|
85
|
+
The behaviour of the `destroy` method has been updated so that it now returns
|
86
|
+
`false` when halted by a before_destroy callback. This is in line with behaviour
|
87
|
+
of ActiveRecord. For more information see
|
88
|
+
[#47](https://github.com/JackDanger/permanent_records/issues/47).
|
89
|
+
|
82
90
|
## Productionizing
|
83
91
|
|
84
92
|
If you operate a system where destroying or reviving a record takes more
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4.0.0
|
data/lib/permanent_records.rb
CHANGED
data/permanent_records.gemspec
CHANGED
@@ -1,43 +1,30 @@
|
|
1
|
-
#
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
|
-
require 'date'
|
7
|
-
|
1
|
+
# encoding: utf-8
|
8
2
|
Gem::Specification.new do |s|
|
9
3
|
s.name = "permanent_records"
|
10
4
|
s.version = File.read('VERSION')
|
11
5
|
s.license = 'MIT'
|
12
6
|
|
13
|
-
s.
|
14
|
-
s.
|
15
|
-
s.date = Date.today.to_s
|
7
|
+
s.authors = ["Jack Danger Canty", "David Sulc", "Joe Nelson", "Trond Arve Nordheim", "Josh Teneycke", "Maximilian Herold", "Hugh Evans"]
|
8
|
+
s.summary = "Soft-delete your ActiveRecord records"
|
16
9
|
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
|
-
s.email = "
|
10
|
+
s.email = "github@jackcanty.com"
|
18
11
|
s.extra_rdoc_files = [
|
19
12
|
"LICENSE",
|
20
|
-
"README.
|
13
|
+
"README.md"
|
21
14
|
]
|
22
|
-
s.files = `git ls-files`.split(
|
15
|
+
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
23
16
|
s.homepage = "https://github.com/JackDanger/permanent_records"
|
24
17
|
s.require_paths = ["lib"]
|
25
|
-
s.rubygems_version = "1.8.17"
|
26
|
-
s.summary = "Soft-delete your ActiveRecord records"
|
27
18
|
|
28
|
-
|
29
|
-
|
19
|
+
# For testing against multiple AR versions
|
20
|
+
ver = ENV['AR_TEST_VERSION']
|
21
|
+
ver = ver.dup.chomp if ver
|
30
22
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
else
|
39
|
-
s.add_dependency(%q<activerecord>, [">= 3.0.0"])
|
40
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
41
|
-
end
|
23
|
+
s.add_runtime_dependency('activerecord', ver || '>= 3.0.0')
|
24
|
+
s.add_runtime_dependency('activesupport', ver || '>= 3.0.0')
|
25
|
+
s.add_development_dependency('sqlite3')
|
26
|
+
s.add_development_dependency('pry')
|
27
|
+
s.add_development_dependency('database_cleaner')
|
28
|
+
s.add_development_dependency('rspec', '~> 2.14.1')
|
42
29
|
end
|
43
30
|
|
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:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jack Danger Canty
|
@@ -10,73 +10,116 @@ authors:
|
|
10
10
|
- Trond Arve Nordheim
|
11
11
|
- Josh Teneycke
|
12
12
|
- Maximilian Herold
|
13
|
+
- Hugh Evans
|
13
14
|
autorequire:
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
|
-
date: 2015-
|
17
|
+
date: 2015-08-12 00:00:00.000000000 Z
|
17
18
|
dependencies:
|
18
19
|
- !ruby/object:Gem::Dependency
|
19
20
|
name: activerecord
|
20
21
|
requirement: !ruby/object:Gem::Requirement
|
21
22
|
requirements:
|
22
|
-
- -
|
23
|
+
- - '='
|
23
24
|
- !ruby/object:Gem::Version
|
24
|
-
version:
|
25
|
+
version: 4.2.0
|
25
26
|
type: :runtime
|
26
27
|
prerelease: false
|
27
28
|
version_requirements: !ruby/object:Gem::Requirement
|
28
29
|
requirements:
|
29
|
-
- -
|
30
|
+
- - '='
|
30
31
|
- !ruby/object:Gem::Version
|
31
|
-
version:
|
32
|
+
version: 4.2.0
|
32
33
|
- !ruby/object:Gem::Dependency
|
33
|
-
name:
|
34
|
+
name: activesupport
|
34
35
|
requirement: !ruby/object:Gem::Requirement
|
35
36
|
requirements:
|
36
|
-
- -
|
37
|
+
- - '='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 4.2.0
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - '='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 4.2.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: sqlite3
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: pry
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '>='
|
37
66
|
- !ruby/object:Gem::Version
|
38
67
|
version: '0'
|
39
68
|
type: :development
|
40
69
|
prerelease: false
|
41
70
|
version_requirements: !ruby/object:Gem::Requirement
|
42
71
|
requirements:
|
43
|
-
- -
|
72
|
+
- - '>='
|
44
73
|
- !ruby/object:Gem::Version
|
45
74
|
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: database_cleaner
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rspec
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ~>
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 2.14.1
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ~>
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 2.14.1
|
46
103
|
description: Never Lose Data. Rather than deleting rows this sets Record#deleted_at
|
47
104
|
and gives you all the scopes you need to work with your data.
|
48
|
-
email:
|
105
|
+
email: github@jackcanty.com
|
49
106
|
executables: []
|
50
107
|
extensions: []
|
51
108
|
extra_rdoc_files:
|
52
109
|
- LICENSE
|
53
|
-
- README.
|
110
|
+
- README.md
|
54
111
|
files:
|
55
|
-
-
|
56
|
-
-
|
57
|
-
-
|
112
|
+
- .document
|
113
|
+
- .gitignore
|
114
|
+
- .travis.yml
|
58
115
|
- CONTRIBUTORS.md
|
59
116
|
- Gemfile
|
60
117
|
- LICENSE
|
61
|
-
- README.
|
118
|
+
- README.md
|
62
119
|
- Rakefile
|
63
120
|
- VERSION
|
64
121
|
- lib/permanent_records.rb
|
65
122
|
- permanent_records.gemspec
|
66
|
-
- spec/permanent_records_spec.rb
|
67
|
-
- spec/spec_helper.rb
|
68
|
-
- spec/support/comment.rb
|
69
|
-
- spec/support/database.yml
|
70
|
-
- spec/support/difficulty.rb
|
71
|
-
- spec/support/dirt.rb
|
72
|
-
- spec/support/earthworm.rb
|
73
|
-
- spec/support/hole.rb
|
74
|
-
- spec/support/kitty.rb
|
75
|
-
- spec/support/location.rb
|
76
|
-
- spec/support/mole.rb
|
77
|
-
- spec/support/muskrat.rb
|
78
|
-
- spec/support/schema.rb
|
79
|
-
- spec/support/unused_model.rb
|
80
123
|
homepage: https://github.com/JackDanger/permanent_records
|
81
124
|
licenses:
|
82
125
|
- MIT
|
@@ -87,19 +130,18 @@ require_paths:
|
|
87
130
|
- lib
|
88
131
|
required_ruby_version: !ruby/object:Gem::Requirement
|
89
132
|
requirements:
|
90
|
-
- -
|
133
|
+
- - '>='
|
91
134
|
- !ruby/object:Gem::Version
|
92
135
|
version: '0'
|
93
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
137
|
requirements:
|
95
|
-
- -
|
138
|
+
- - '>='
|
96
139
|
- !ruby/object:Gem::Version
|
97
140
|
version: '0'
|
98
141
|
requirements: []
|
99
142
|
rubyforge_project:
|
100
|
-
rubygems_version: 2.
|
143
|
+
rubygems_version: 2.0.14
|
101
144
|
signing_key:
|
102
|
-
specification_version:
|
145
|
+
specification_version: 4
|
103
146
|
summary: Soft-delete your ActiveRecord records
|
104
147
|
test_files: []
|
105
|
-
has_rdoc:
|
@@ -1,348 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe PermanentRecords do
|
4
|
-
|
5
|
-
let!(:frozen_moment) { Time.now }
|
6
|
-
let!(:dirt) { Dirt.create! }
|
7
|
-
let!(:earthworm) { dirt.create_earthworm }
|
8
|
-
let!(:hole) { dirt.create_hole(:options => {}) }
|
9
|
-
let!(:muskrat) { hole.muskrats.create! }
|
10
|
-
let!(:mole) { hole.moles.create! }
|
11
|
-
let!(:location) { hole.create_location }
|
12
|
-
let!(:difficulty) { hole.create_difficulty }
|
13
|
-
let!(:comments) { 2.times.map {hole.comments.create!} }
|
14
|
-
let!(:kitty) { Kitty.create! }
|
15
|
-
|
16
|
-
|
17
|
-
describe '#destroy' do
|
18
|
-
|
19
|
-
let(:record) { hole }
|
20
|
-
let(:should_force) { false }
|
21
|
-
|
22
|
-
subject { record.destroy should_force }
|
23
|
-
|
24
|
-
it 'returns the record' do
|
25
|
-
subject.should == record
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'makes deleted? return true' do
|
29
|
-
subject.should be_deleted
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'sets the deleted_at attribute' do
|
33
|
-
subject.deleted_at.should be_within(0.1).of(Time.now)
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'does not really remove the record' do
|
37
|
-
expect { subject }.to_not change { record.class.count }
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'handles serialized attributes correctly' do
|
41
|
-
expect(subject.options).to eq({})
|
42
|
-
expect(subject.size).to be_nil if record.respond_to?(:size)
|
43
|
-
end
|
44
|
-
|
45
|
-
context 'with force argument set to truthy' do
|
46
|
-
let(:should_force) { :force }
|
47
|
-
|
48
|
-
it 'does really remove the record' do
|
49
|
-
expect { subject }.to change { record.class.count }.by(-1)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
context 'with hash-style :force argument' do
|
54
|
-
let(:should_force) {{ force: true }}
|
55
|
-
|
56
|
-
it 'does really remove the record' do
|
57
|
-
expect { subject }.to change { record.class.count }.by(-1)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
context 'when validations fail' do
|
62
|
-
before {
|
63
|
-
Hole.any_instance.stub(:valid?).and_return(false)
|
64
|
-
}
|
65
|
-
it 'raises' do
|
66
|
-
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
|
67
|
-
end
|
68
|
-
|
69
|
-
context 'with validation opt-out' do
|
70
|
-
let(:should_force) {{ validate: false }}
|
71
|
-
it 'doesnt raise' do
|
72
|
-
expect { subject }.to_not raise_error
|
73
|
-
end
|
74
|
-
it 'soft-deletes the invalid record' do
|
75
|
-
subject.should be_deleted
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
context 'when model has no deleted_at column' do
|
81
|
-
let(:record) { kitty }
|
82
|
-
|
83
|
-
it 'really removes the record' do
|
84
|
-
expect { subject }.to change { record.class.count }.by(-1)
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'makes deleted? return true' do
|
88
|
-
subject.should be_deleted
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'with dependent records' do
|
93
|
-
context 'that are permanent' do
|
94
|
-
it '' do
|
95
|
-
expect { subject }.to_not change { Muskrat.count }
|
96
|
-
end
|
97
|
-
|
98
|
-
context 'with has_many cardinality' do
|
99
|
-
it 'marks records as deleted' do
|
100
|
-
subject.muskrats.each {|m| m.should be_deleted }
|
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
|
-
|
111
|
-
context 'with force delete' do
|
112
|
-
let(:should_force) { :force }
|
113
|
-
it('') { expect { subject }.to change { Muskrat.count }.by(-1) }
|
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
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
context 'with has_one cardinality' do
|
125
|
-
it 'marks records as deleted' do
|
126
|
-
subject.location.should be_deleted
|
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
|
-
|
137
|
-
context 'with force delete' do
|
138
|
-
let(:should_force) { :force }
|
139
|
-
it('') { expect { subject }.to change { Muskrat.count }.by(-1) }
|
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
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
context 'that are non-permanent' do
|
176
|
-
it 'removes them' do
|
177
|
-
expect { subject }.to change { Mole.count }.by(-1)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
context 'as default scope' do
|
182
|
-
let(:load_comments) { Comment.unscoped.where(:hole_id => subject.id) }
|
183
|
-
context 'with :has_many cardinality' do
|
184
|
-
before {
|
185
|
-
load_comments.size.should == 2
|
186
|
-
}
|
187
|
-
it 'deletes them' do
|
188
|
-
load_comments.all?(&:deleted?).should be_true
|
189
|
-
subject.comments.should be_blank
|
190
|
-
end
|
191
|
-
end
|
192
|
-
context 'with :has_one cardinality' do
|
193
|
-
it 'deletes them' do
|
194
|
-
subject.difficulty.should be_deleted
|
195
|
-
Difficulty.find_by_id(subject.difficulty.id).should be_nil
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
describe '#revive' do
|
203
|
-
|
204
|
-
let!(:record) { hole.destroy }
|
205
|
-
let(:should_validate) { nil }
|
206
|
-
|
207
|
-
subject { record.revive should_validate }
|
208
|
-
|
209
|
-
it 'returns the record' do
|
210
|
-
subject.should == record
|
211
|
-
end
|
212
|
-
|
213
|
-
it 'unsets deleted_at' do
|
214
|
-
expect { subject }.to change {
|
215
|
-
record.deleted_at
|
216
|
-
}.to(nil)
|
217
|
-
end
|
218
|
-
|
219
|
-
it 'makes deleted? return false' do
|
220
|
-
subject.should_not be_deleted
|
221
|
-
end
|
222
|
-
|
223
|
-
context 'when validations fail' do
|
224
|
-
before {
|
225
|
-
Hole.any_instance.stub(:valid?).and_return(false)
|
226
|
-
}
|
227
|
-
it 'raises' do
|
228
|
-
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
|
229
|
-
end
|
230
|
-
|
231
|
-
context 'with validation opt-out' do
|
232
|
-
let(:should_validate) {{ validate: false }}
|
233
|
-
it 'doesnt raise' do
|
234
|
-
expect { subject }.to_not raise_error
|
235
|
-
end
|
236
|
-
it 'makes deleted? return false' do
|
237
|
-
subject.should_not be_deleted
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
context 'with dependent records' do
|
243
|
-
context 'that are permanent' do
|
244
|
-
it '' do
|
245
|
-
expect { subject }.to_not change { Muskrat.count }
|
246
|
-
end
|
247
|
-
|
248
|
-
context 'that were deleted previously' do
|
249
|
-
before { muskrat.update_attributes! :deleted_at => 2.minutes.ago }
|
250
|
-
it 'does not restore' do
|
251
|
-
expect { subject }.to_not change { muskrat.deleted? }
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
context 'with has_many cardinality' do
|
256
|
-
it 'revives them' do
|
257
|
-
subject.muskrats.each {|m| m.should_not be_deleted }
|
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
|
266
|
-
end
|
267
|
-
|
268
|
-
context 'with has_one cardinality' do
|
269
|
-
it 'revives them' do
|
270
|
-
subject.location.should_not be_deleted
|
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
|
293
|
-
end
|
294
|
-
end
|
295
|
-
|
296
|
-
context 'that are non-permanent' do
|
297
|
-
it 'cannot revive them' do
|
298
|
-
expect { subject }.to_not change { Mole.count }
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
context 'as default scope' do
|
303
|
-
context 'with :has_many cardinality' do
|
304
|
-
its('comments.size') { should == 2 }
|
305
|
-
it 'revives them' do
|
306
|
-
subject.comments.each {|c| c.should_not be_deleted }
|
307
|
-
subject.comments.each {|c| Comment.find_by_id(c.id).should == c }
|
308
|
-
end
|
309
|
-
end
|
310
|
-
context 'with :has_one cardinality' do
|
311
|
-
it 'revives them' do
|
312
|
-
subject.difficulty.should_not be_deleted
|
313
|
-
Difficulty.find_by_id(subject.difficulty.id).should == difficulty
|
314
|
-
end
|
315
|
-
end
|
316
|
-
end
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
|
-
describe 'scopes' do
|
321
|
-
|
322
|
-
before {
|
323
|
-
3.times { Muskrat.create! }
|
324
|
-
6.times { Muskrat.create!.destroy }
|
325
|
-
}
|
326
|
-
|
327
|
-
context '.not_deleted' do
|
328
|
-
|
329
|
-
it 'counts' do
|
330
|
-
Muskrat.not_deleted.count.should == Muskrat.all.reject(&:deleted?).size
|
331
|
-
end
|
332
|
-
|
333
|
-
it 'has no deleted records' do
|
334
|
-
Muskrat.not_deleted.each {|m| m.should_not be_deleted }
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
context '.deleted' do
|
339
|
-
it 'counts' do
|
340
|
-
Muskrat.deleted.count.should == Muskrat.all.select(&:deleted?).size
|
341
|
-
end
|
342
|
-
|
343
|
-
it 'has no non-deleted records' do
|
344
|
-
Muskrat.deleted.each {|m| m.should be_deleted }
|
345
|
-
end
|
346
|
-
end
|
347
|
-
end
|
348
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
|
2
|
-
# Include this file in your test by copying the following line to your test:
|
3
|
-
# require File.expand_path(File.dirname(__FILE__) + "/test_helper")
|
4
|
-
|
5
|
-
lib = Pathname.new File.expand_path('../../lib', File.dirname(__FILE__))
|
6
|
-
support = Pathname.new File.expand_path('../spec/support', File.dirname(__FILE__))
|
7
|
-
$:.unshift lib
|
8
|
-
$:.unshift support
|
9
|
-
RAILS_ROOT = File.dirname(__FILE__)
|
10
|
-
|
11
|
-
require 'active_record'
|
12
|
-
require 'active_support'
|
13
|
-
require 'permanent_records'
|
14
|
-
require 'awesome_print'
|
15
|
-
|
16
|
-
module Rails
|
17
|
-
def self.env; 'test'end
|
18
|
-
end
|
19
|
-
|
20
|
-
if I18n.config.respond_to?(:enforce_available_locales)
|
21
|
-
I18n.config.enforce_available_locales = true
|
22
|
-
end
|
23
|
-
|
24
|
-
require 'logger'
|
25
|
-
ActiveRecord::Base.logger = Logger.new support.join("debug.log")
|
26
|
-
ActiveRecord::Base.configurations = YAML::load_file support.join('database.yml')
|
27
|
-
ActiveRecord::Base.establish_connection
|
28
|
-
|
29
|
-
load 'schema.rb' if File.exist?(support.join('schema.rb'))
|
30
|
-
|
31
|
-
Dir.glob(support.join('*.rb')).each do |file|
|
32
|
-
autoload File.basename(file).chomp('.rb').camelcase.intern, file
|
33
|
-
end.each do |file|
|
34
|
-
require file
|
35
|
-
end
|
36
|
-
|
37
|
-
require 'database_cleaner'
|
38
|
-
|
39
|
-
RSpec.configure do |config|
|
40
|
-
config.before(:suite) do
|
41
|
-
DatabaseCleaner.strategy = :transaction
|
42
|
-
DatabaseCleaner.clean_with(:truncation)
|
43
|
-
end
|
44
|
-
|
45
|
-
config.before(:each) do
|
46
|
-
DatabaseCleaner.start
|
47
|
-
end
|
48
|
-
|
49
|
-
config.after(:each) do
|
50
|
-
DatabaseCleaner.clean
|
51
|
-
end
|
52
|
-
end
|
data/spec/support/comment.rb
DELETED
data/spec/support/database.yml
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
test:
|
2
|
-
:adapter: sqlite3
|
3
|
-
:database: ":memory:"
|
4
|
-
:min_messages: ERROR
|
5
|
-
# sqlite:
|
6
|
-
# :adapter: sqlite
|
7
|
-
# :database: plugin.sqlite.db
|
8
|
-
# sqlite3:
|
9
|
-
# :adapter: sqlite3
|
10
|
-
# :database: ":memory:"
|
11
|
-
# mysql:
|
12
|
-
# :adapter: mysql
|
13
|
-
# :host: localhost
|
14
|
-
# :username: rails
|
15
|
-
# :password:
|
16
|
-
# :database: plugin_test
|
data/spec/support/difficulty.rb
DELETED
data/spec/support/dirt.rb
DELETED
data/spec/support/earthworm.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
class Earthworm < ActiveRecord::Base
|
2
|
-
belongs_to :dirt
|
3
|
-
|
4
|
-
# Earthworms have been known to complain if they're left on their deathbeds without any dirt
|
5
|
-
before_destroy :complain!
|
6
|
-
|
7
|
-
def complain!
|
8
|
-
raise "Where's my dirt?!" if Dirt.not_deleted.find(self.dirt_id).nil?
|
9
|
-
end
|
10
|
-
|
11
|
-
end
|
data/spec/support/hole.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
class Hole < ActiveRecord::Base
|
2
|
-
# Because when we're destroying a mole hole we're obviously using high explosives.
|
3
|
-
belongs_to :dirt, :dependent => :destroy
|
4
|
-
|
5
|
-
# muskrats are permanent
|
6
|
-
has_many :muskrats, :dependent => :destroy
|
7
|
-
# moles are not permanent
|
8
|
-
has_many :moles, :dependent => :destroy
|
9
|
-
|
10
|
-
has_one :location, :dependent => :destroy
|
11
|
-
has_one :unused_model, :dependent => :destroy
|
12
|
-
has_one :difficulty, :dependent => :destroy
|
13
|
-
has_many :comments, :dependent => :destroy
|
14
|
-
|
15
|
-
serialize :options, Hash
|
16
|
-
store :properties, :accessors => [:size] if respond_to?(:store)
|
17
|
-
end
|
data/spec/support/kitty.rb
DELETED
data/spec/support/location.rb
DELETED
data/spec/support/mole.rb
DELETED
data/spec/support/muskrat.rb
DELETED
data/spec/support/schema.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
ActiveRecord::Schema.define(:version => 1) do
|
2
|
-
|
3
|
-
create_table :muskrats, :force => true do |t|
|
4
|
-
t.column :name, :string
|
5
|
-
t.column :deleted_at, :datetime
|
6
|
-
t.references :hole
|
7
|
-
end
|
8
|
-
|
9
|
-
create_table :kitties, :force => true do |t|
|
10
|
-
t.column :name, :string
|
11
|
-
end
|
12
|
-
|
13
|
-
create_table :holes, :force => true do |t|
|
14
|
-
t.integer :number
|
15
|
-
t.text :options
|
16
|
-
t.text :properties
|
17
|
-
t.references :dirt
|
18
|
-
t.datetime :deleted_at
|
19
|
-
end
|
20
|
-
|
21
|
-
create_table :moles, :force => true do |t|
|
22
|
-
t.string :name
|
23
|
-
t.references :hole
|
24
|
-
end
|
25
|
-
|
26
|
-
create_table :locations, :force => true do |t|
|
27
|
-
t.string :name
|
28
|
-
t.references :hole
|
29
|
-
t.datetime :deleted_at
|
30
|
-
end
|
31
|
-
|
32
|
-
create_table :comments, :force => true do |t|
|
33
|
-
t.string :text
|
34
|
-
t.references :hole
|
35
|
-
t.datetime :deleted_at
|
36
|
-
end
|
37
|
-
|
38
|
-
create_table :difficulties, :force => true do |t|
|
39
|
-
t.string :name
|
40
|
-
t.references :hole
|
41
|
-
t.datetime :deleted_at
|
42
|
-
end
|
43
|
-
|
44
|
-
create_table :unused_models, :force => true do |t|
|
45
|
-
t.string :name
|
46
|
-
t.references :hole
|
47
|
-
t.datetime :deleted_at
|
48
|
-
end
|
49
|
-
|
50
|
-
create_table :dirts, :force => true do |t|
|
51
|
-
t.string :color
|
52
|
-
t.datetime :deleted_at
|
53
|
-
end
|
54
|
-
|
55
|
-
create_table :earthworms, :force => true do |t|
|
56
|
-
t.references :dirt
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|