acts_as_paranoid 0.6.0 → 0.7.1
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/CHANGELOG.md +128 -0
- data/README.md +154 -56
- data/lib/acts_as_paranoid.rb +34 -31
- data/lib/acts_as_paranoid/associations.rb +21 -17
- data/lib/acts_as_paranoid/core.rb +139 -58
- data/lib/acts_as_paranoid/relation.rb +2 -0
- data/lib/acts_as_paranoid/validations.rb +8 -69
- data/lib/acts_as_paranoid/version.rb +3 -1
- data/test/test_associations.rb +157 -38
- data/test/test_core.rb +269 -48
- data/test/test_default_scopes.rb +7 -6
- data/test/test_helper.rb +155 -62
- data/test/test_inheritance.rb +3 -1
- data/test/test_relations.rb +18 -10
- data/test/test_validations.rb +9 -7
- metadata +92 -33
- data/lib/acts_as_paranoid/preloader_association.rb +0 -16
- data/test/test_preloader_association.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '096b348280798fe5ac4770a6c57bdb0731d2c5df9e7d361551cf065fe71f0b56'
|
4
|
+
data.tar.gz: 3d923644ebb1ccb3e06d9c04d8a0797f1677fcec880a188dd04ec8b19c9a957a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e677d8e734d9c6d72fd68feaad170f928fb159ea6a90e400632ce8365f8120a991eae46508bb04d641117fa2e24d3e38e9df6699c1d70b2cd994a4cf85c49379
|
7
|
+
data.tar.gz: b58a42cbf60696baffac255deb673476e5e339dbbe4bd1681959442ca2fc33a51f6d2e146755fc8f79539976d47c6244927969c82a86fdb70a553de44281e512
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
Notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
## 0.7.1
|
6
|
+
|
7
|
+
* Support Rails 6.1 ([#191], by [Matijs van Zuijlen][mvz])
|
8
|
+
* Support `belongs_to` with both `:touch` and `:counter_cache` options ([#208],
|
9
|
+
by [Matijs van Zuijlen][mvz] with [Paul Druziak][pauldruziak])
|
10
|
+
* Support Ruby 3.0 ([#209], by [Matijs van Zuijlen][mvz])
|
11
|
+
|
12
|
+
## 0.7.0
|
13
|
+
|
14
|
+
### Breaking changes
|
15
|
+
|
16
|
+
* Support Rails 5.2+ only ([#126], by [Daniel Rice][danielricecodes])
|
17
|
+
* Update set of supported rubies to 2.4-2.7 ([#144], [#173] by [Matijs van Zuijlen][mvz])
|
18
|
+
|
19
|
+
### Improvements
|
20
|
+
|
21
|
+
* Handle `with_deleted` association option as a scope ([#147], by [Matijs van Zuijlen][mvz])
|
22
|
+
* Simplify validation override ([#158], by [Matijs van Zuijlen][mvz])
|
23
|
+
* Use correct unscope syntax so unscope works on Rails Edge ([#160],
|
24
|
+
by [Matijs van Zuijlen][mvz])
|
25
|
+
* Fix ruby 2.7 keyword argument deprecation warning ([#161], by [Jon Riddle][wtfspm])
|
26
|
+
|
27
|
+
### Documentation
|
28
|
+
|
29
|
+
* Document save after destroy behavior ([#146], by [Matijs van Zuijlen][mvz])
|
30
|
+
* Update version number instructions for installing gem ([#164],
|
31
|
+
by [Kevin McAlear][kevinmcalear])
|
32
|
+
* Add example with `destroyed_fully?` and `deleted_fully?` to the readme ([#170],
|
33
|
+
by [Kiril Mitov][thebravoman])
|
34
|
+
|
35
|
+
### Internal
|
36
|
+
|
37
|
+
* Improve code quality using RuboCop ([#148], [#152], [#159], [#163], [#171] and [#173],
|
38
|
+
by [Matijs van Zuijlen][mvz])
|
39
|
+
* Measure code coverage using SimpleCov ([#150] and [#175] by [Matijs van Zuijlen][mvz])
|
40
|
+
* Silence warnings emitted during tests ([#156], by [Matijs van Zuijlen][mvz])
|
41
|
+
* Make rake tasks more robust and intuitive ([#157], by [Matijs van Zuijlen][mvz])
|
42
|
+
|
43
|
+
## 0.6.3
|
44
|
+
|
45
|
+
* Update Travis CI configuration ([#137], by [Matijs van Zuijlen][mvz])
|
46
|
+
* Add predicate to check if record was soft deleted or hard deleted ([#136],
|
47
|
+
by [Aymeric Le Dorze][aymeric-ledorze])
|
48
|
+
* Add support for recover! method ([#75], by [vinoth][avinoth])
|
49
|
+
* Fix a record being dirty after destroying it ([#135], by
|
50
|
+
[Aymeric Le Dorze][aymeric-ledorze])
|
51
|
+
|
52
|
+
## 0.6.2
|
53
|
+
|
54
|
+
* Prevent recovery of non-deleted records
|
55
|
+
([#133], by [Mary Beliveau][marycodes2] and [Valerie Woolard][valeriecodes])
|
56
|
+
* Allow model to set `table_name` after `acts_as_paranoid` macro
|
57
|
+
([#131], by [Alex Wheeler][AlexWheeler])
|
58
|
+
* Make counter cache work with a custom column name and with optional
|
59
|
+
associations ([#123], by [Ned Campion][nedcampion])
|
60
|
+
|
61
|
+
## 0.6.1
|
62
|
+
|
63
|
+
* Add support for Rails 6 ([#124], by [Daniel Rice][danielricecodes],
|
64
|
+
[Josh Bryant][jbryant92], and [Romain Alexandre][RomainAlexandre])
|
65
|
+
* Add support for incrementing and decrementing counter cache columns on
|
66
|
+
associated objects ([#119], by [Dimitar Lukanov][shadydealer])
|
67
|
+
* Add `:double_tap_destroys_fully` option, with default `true` ([#116],
|
68
|
+
by [Michael Riviera][ri4a])
|
69
|
+
* Officially support Ruby 2.6 ([#114], by [Matijs van Zuijlen][mvz])
|
70
|
+
|
71
|
+
## 0.6.0 and earlier
|
72
|
+
|
73
|
+
(To be added)
|
74
|
+
|
75
|
+
<!-- Contributors -->
|
76
|
+
|
77
|
+
[AlexWheeler]: https://github.com/AlexWheeler
|
78
|
+
[RomainAlexandre]: https://github.com/RomainAlexandre
|
79
|
+
[avinoth]: https://github.com/avinoth
|
80
|
+
[aymeric-ledorze]: https://github.com/aymeric-ledorze
|
81
|
+
[danielricecodes]: https://github.com/danielricecodes
|
82
|
+
[jbryant92]: https://github.com/jbryant92
|
83
|
+
[kevinmcalear]: https://github.com/kevinmcalear
|
84
|
+
[marycodes2]: https://github.com/marycodes2
|
85
|
+
[mvz]: https://github.com/mvz
|
86
|
+
[nedcampion]: https://github.com/nedcampion
|
87
|
+
[ri4a]: https://github.com/ri4a
|
88
|
+
[pauldruziak]: https://github.com/pauldruziak
|
89
|
+
[shadydealer]: https://github.com/shadydealer
|
90
|
+
[thebravoman]: https://github.com/thebravoman
|
91
|
+
[valeriecodes]: https://github.com/valeriecodes
|
92
|
+
[wtfspm]: https://github.com/wtfspm
|
93
|
+
|
94
|
+
<!-- issues & pull requests -->
|
95
|
+
|
96
|
+
[#209]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/209
|
97
|
+
[#208]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/208
|
98
|
+
[#191]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/191
|
99
|
+
[#175]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/175
|
100
|
+
[#173]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/173
|
101
|
+
[#171]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/171
|
102
|
+
[#170]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/170
|
103
|
+
[#164]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/164
|
104
|
+
[#163]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/163
|
105
|
+
[#161]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/161
|
106
|
+
[#160]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/160
|
107
|
+
[#159]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/159
|
108
|
+
[#158]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/158
|
109
|
+
[#157]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/157
|
110
|
+
[#156]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/156
|
111
|
+
[#152]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/152
|
112
|
+
[#150]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/150
|
113
|
+
[#148]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/148
|
114
|
+
[#147]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/147
|
115
|
+
[#146]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/146
|
116
|
+
[#144]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/144
|
117
|
+
[#137]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/137
|
118
|
+
[#136]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/136
|
119
|
+
[#135]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/135
|
120
|
+
[#133]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/133
|
121
|
+
[#131]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/131
|
122
|
+
[#126]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/126
|
123
|
+
[#124]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/124
|
124
|
+
[#123]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/123
|
125
|
+
[#119]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/119
|
126
|
+
[#116]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/116
|
127
|
+
[#114]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/114
|
128
|
+
[#75]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/75
|
data/README.md
CHANGED
@@ -9,35 +9,38 @@ recoverable later.
|
|
9
9
|
|
10
10
|
## Support
|
11
11
|
|
12
|
-
**This branch targets Rails
|
12
|
+
**This branch targets Rails 5.2+ and Ruby 2.4+ only**
|
13
13
|
|
14
|
-
If you're working with
|
15
|
-
require an older version of the
|
14
|
+
If you're working with Rails 5.1 and earlier, or with Ruby 2.3 or earlier,
|
15
|
+
please switch to the corresponding branch or require an older version of the
|
16
|
+
`acts_as_paranoid` gem.
|
16
17
|
|
17
|
-
### Known issues
|
18
|
+
### Known issues
|
18
19
|
|
19
|
-
* Using acts_as_paranoid and ActiveStorage on the same model
|
20
|
+
* Using `acts_as_paranoid` and ActiveStorage on the same model
|
20
21
|
[leads to a SystemStackError](https://github.com/ActsAsParanoid/acts_as_paranoid/issues/103).
|
21
|
-
* You cannot directly create a model in a deleted state
|
22
|
+
* You cannot directly create a model in a deleted state, or update a model
|
23
|
+
after it's been deleted.
|
22
24
|
|
23
25
|
## Usage
|
24
26
|
|
25
27
|
#### Install gem:
|
26
28
|
|
27
|
-
```
|
28
|
-
gem 'acts_as_paranoid', '~> 0.
|
29
|
+
```ruby
|
30
|
+
gem 'acts_as_paranoid', '~> 0.7.0'
|
29
31
|
```
|
30
|
-
|
32
|
+
|
33
|
+
```shell
|
31
34
|
bundle install
|
32
35
|
```
|
33
36
|
|
34
37
|
#### Create migration
|
35
38
|
|
36
|
-
```
|
39
|
+
```shell
|
37
40
|
bin/rails generate migration AddDeletedAtToParanoiac deleted_at:datetime:index
|
38
41
|
```
|
39
42
|
|
40
|
-
#### Enable ActsAsParanoid
|
43
|
+
#### Enable ActsAsParanoid
|
41
44
|
|
42
45
|
```ruby
|
43
46
|
class Paranoiac < ActiveRecord::Base
|
@@ -45,31 +48,42 @@ class Paranoiac < ActiveRecord::Base
|
|
45
48
|
end
|
46
49
|
```
|
47
50
|
|
48
|
-
|
49
|
-
|
50
|
-
- `:column => 'deleted_at'`
|
51
|
-
- `:column_type => 'time'`
|
51
|
+
By default, ActsAsParanoid assumes a record's *deletion* is stored in a
|
52
|
+
`datetime` column called `deleted_at`.
|
52
53
|
|
53
54
|
### Options
|
54
55
|
|
55
|
-
If you are using a different column name and type to store a record's
|
56
|
+
If you are using a different column name and type to store a record's
|
57
|
+
*deletion*, you can specify them as follows:
|
56
58
|
|
57
|
-
-
|
58
|
-
-
|
59
|
+
- `column: 'deleted'`
|
60
|
+
- `column_type: 'boolean'`
|
59
61
|
|
60
|
-
While *column* can be anything (as long as it exists in your database), *type*
|
62
|
+
While *column* can be anything (as long as it exists in your database), *type*
|
63
|
+
is restricted to:
|
61
64
|
|
62
65
|
- `boolean`
|
63
66
|
- `time` or
|
64
67
|
- `string`
|
65
68
|
|
66
|
-
|
69
|
+
Note that the `time` type corresponds to the database column type `datetime`
|
70
|
+
in your Rails migrations and schema.
|
67
71
|
|
68
|
-
If your column type is a `
|
72
|
+
If your column type is a `string`, you can also specify which value to use when
|
73
|
+
marking an object as deleted by passing `:deleted_value` (default is
|
74
|
+
"deleted"). Any records with a non-matching value in this column will be
|
75
|
+
treated normally, i.e., as not deleted.
|
76
|
+
|
77
|
+
If your column type is a `boolean`, it is possible to specify `allow_nulls`
|
78
|
+
option which is `true` by default. When set to `false`, entities that have
|
79
|
+
`false` value in this column will be considered not deleted, and those which
|
80
|
+
have `true` will be considered deleted. When `true` everything that has a
|
81
|
+
not-null value will be considered deleted.
|
69
82
|
|
70
83
|
### Filtering
|
71
84
|
|
72
|
-
If a record is deleted by ActsAsParanoid, it won't be retrieved when accessing
|
85
|
+
If a record is deleted by ActsAsParanoid, it won't be retrieved when accessing
|
86
|
+
the database.
|
73
87
|
|
74
88
|
So, `Paranoiac.all` will **not** include the **deleted records**.
|
75
89
|
|
@@ -80,7 +94,8 @@ Paranoiac.only_deleted # retrieves only the deleted records
|
|
80
94
|
Paranoiac.with_deleted # retrieves all records, deleted or not
|
81
95
|
```
|
82
96
|
|
83
|
-
When using the default `column_type` of `'time'`, the following extra scopes
|
97
|
+
When using the default `column_type` of `'time'`, the following extra scopes
|
98
|
+
are provided:
|
84
99
|
|
85
100
|
```ruby
|
86
101
|
time = Time.now
|
@@ -100,20 +115,33 @@ In order to really delete a record, just use:
|
|
100
115
|
paranoiac.destroy_fully!
|
101
116
|
Paranoiac.delete_all!(conditions)
|
102
117
|
```
|
103
|
-
**NOTE:** The `.destroy!` method is still usable, but equivalent to `.destroy`. It just hides the object.
|
104
118
|
|
105
|
-
|
119
|
+
**NOTE:** The `.destroy!` method is still usable, but equivalent to `.destroy`.
|
120
|
+
It just hides the object.
|
121
|
+
|
122
|
+
Alternatively you can permanently delete a record by calling `destroy` or
|
123
|
+
`delete_all` on the object **twice**.
|
106
124
|
|
107
|
-
If a record was already deleted (hidden by `ActsAsParanoid`) and you delete it
|
125
|
+
If a record was already deleted (hidden by `ActsAsParanoid`) and you delete it
|
126
|
+
again, it will be removed from the database.
|
108
127
|
|
109
128
|
Take this example:
|
110
129
|
|
111
130
|
```ruby
|
112
131
|
p = Paranoiac.first
|
113
|
-
|
114
|
-
|
132
|
+
|
133
|
+
# does NOT delete the first record, just hides it
|
134
|
+
p.destroy
|
135
|
+
|
136
|
+
# deletes the first record from the database
|
137
|
+
Paranoiac.only_deleted.where(id: p.id).first.destroy
|
115
138
|
```
|
116
139
|
|
140
|
+
This behaviour can be disabled by setting the configuration option. In a future
|
141
|
+
version, `false` will be the default setting.
|
142
|
+
|
143
|
+
- `double_tap_destroys_fully: false`
|
144
|
+
|
117
145
|
### Recovery
|
118
146
|
|
119
147
|
Recovery is easy. Just invoke `recover` on it, like this:
|
@@ -122,34 +150,39 @@ Recovery is easy. Just invoke `recover` on it, like this:
|
|
122
150
|
Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover
|
123
151
|
```
|
124
152
|
|
125
|
-
All associations marked as
|
153
|
+
All associations marked as `dependent: :destroy` are also recursively recovered.
|
126
154
|
|
127
|
-
If you would like to disable this behavior, you can call `recover` with the
|
155
|
+
If you would like to disable this behavior, you can call `recover` with the
|
156
|
+
`recursive` option:
|
128
157
|
|
129
158
|
```ruby
|
130
|
-
Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover(:
|
159
|
+
Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover(recursive: false)
|
131
160
|
```
|
132
161
|
|
133
|
-
If you would like to change this default behavior for one model, you can use
|
162
|
+
If you would like to change this default behavior for one model, you can use
|
163
|
+
the `recover_dependent_associations` option
|
134
164
|
|
135
165
|
```ruby
|
136
166
|
class Paranoiac < ActiveRecord::Base
|
137
|
-
acts_as_paranoid :
|
167
|
+
acts_as_paranoid recover_dependent_associations: false
|
138
168
|
end
|
139
169
|
```
|
140
170
|
|
141
|
-
By default, dependent records will be recovered if they were deleted within 2
|
171
|
+
By default, dependent records will be recovered if they were deleted within 2
|
172
|
+
minutes of the object upon which they depend.
|
142
173
|
|
143
|
-
This restores the objects to the state before the recursive deletion without
|
174
|
+
This restores the objects to the state before the recursive deletion without
|
175
|
+
restoring other objects that were deleted earlier.
|
144
176
|
|
145
|
-
The behavior is only available when both parent and dependant are using
|
177
|
+
The behavior is only available when both parent and dependant are using
|
178
|
+
timestamp fields to mark deletion, which is the default behavior.
|
146
179
|
|
147
180
|
This window can be changed with the `dependent_recovery_window` option:
|
148
181
|
|
149
182
|
```ruby
|
150
183
|
class Paranoiac < ActiveRecord::Base
|
151
184
|
acts_as_paranoid
|
152
|
-
has_many :paranoids, :
|
185
|
+
has_many :paranoids, dependent: :destroy
|
153
186
|
end
|
154
187
|
|
155
188
|
class Paranoid < ActiveRecord::Base
|
@@ -157,18 +190,42 @@ class Paranoid < ActiveRecord::Base
|
|
157
190
|
|
158
191
|
# Paranoid objects will be recovered alongside Paranoic objects
|
159
192
|
# if they were deleted within 10 minutes of the Paranoic object
|
160
|
-
acts_as_paranoid :
|
193
|
+
acts_as_paranoid dependent_recovery_window: 10.minutes
|
161
194
|
end
|
162
195
|
```
|
163
196
|
|
164
197
|
or in the recover statement
|
165
198
|
|
166
199
|
```ruby
|
167
|
-
Paranoiac.only_deleted.where("name = ?", "not dead yet").first
|
200
|
+
Paranoiac.only_deleted.where("name = ?", "not dead yet").first
|
201
|
+
.recover(recovery_window: 30.seconds)
|
202
|
+
```
|
203
|
+
|
204
|
+
### recover!
|
205
|
+
|
206
|
+
You can invoke `recover!` if you wish to raise an error if the recovery fails.
|
207
|
+
The error generally stems from ActiveRecord.
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover!
|
211
|
+
# => ActiveRecord::RecordInvalid: Validation failed: Name already exists
|
212
|
+
```
|
213
|
+
|
214
|
+
Optionally, you may also raise the error by passing `raise_error: true` to the
|
215
|
+
`recover` method. This behaves the same as `recover!`.
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover(raise_error: true)
|
168
219
|
```
|
169
220
|
|
170
221
|
### Validation
|
171
|
-
|
222
|
+
|
223
|
+
ActiveRecord's built-in uniqueness validation does not account for records
|
224
|
+
deleted by ActsAsParanoid. If you want to check for uniqueness among
|
225
|
+
non-deleted records only, use the macro `validates_as_paranoid` in your model.
|
226
|
+
Then, instead of using `validates_uniqueness_of`, use
|
227
|
+
`validates_uniqueness_of_without_deleted`. This will keep deleted records from
|
228
|
+
counting against the uniqueness check.
|
172
229
|
|
173
230
|
```ruby
|
174
231
|
class Paranoiac < ActiveRecord::Base
|
@@ -177,10 +234,10 @@ class Paranoiac < ActiveRecord::Base
|
|
177
234
|
validates_uniqueness_of_without_deleted :name
|
178
235
|
end
|
179
236
|
|
180
|
-
p1 = Paranoiac.create(:
|
237
|
+
p1 = Paranoiac.create(name: 'foo')
|
181
238
|
p1.destroy
|
182
239
|
|
183
|
-
p2 = Paranoiac.new(:
|
240
|
+
p2 = Paranoiac.new(name: 'foo')
|
184
241
|
p2.valid? #=> true
|
185
242
|
p2.save
|
186
243
|
|
@@ -188,16 +245,34 @@ p1.recover #=> fails validation!
|
|
188
245
|
```
|
189
246
|
|
190
247
|
### Status
|
191
|
-
|
248
|
+
|
249
|
+
A paranoid object could be deleted or destroyed fully.
|
250
|
+
|
251
|
+
You can check if the object is deleted with the `deleted?` helper
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
Paranoiac.create(name: 'foo').destroy
|
255
|
+
Paranoiac.with_deleted.first.deleted? #=> true
|
256
|
+
```
|
257
|
+
|
258
|
+
After the first call to `.destroy` the object is `deleted?`.
|
259
|
+
|
260
|
+
You can check if the object is fully destroyed with `destroyed_fully?` or `deleted_fully?`.
|
192
261
|
|
193
262
|
```ruby
|
194
|
-
Paranoiac.create(:
|
263
|
+
Paranoiac.create(name: 'foo').destroy
|
195
264
|
Paranoiac.with_deleted.first.deleted? #=> true
|
265
|
+
Paranoiac.with_deleted.first.destroyed_fully? #=> false
|
266
|
+
p1 = Paranoiac.with_deleted.first
|
267
|
+
p1.destroy # this fully destroys the object
|
268
|
+
p1.destroyed_fully? #=> true
|
269
|
+
p1.deleted_fully? #=> true
|
196
270
|
```
|
197
271
|
|
198
272
|
### Scopes
|
199
273
|
|
200
|
-
As you've probably guessed, `with_deleted` and `only_deleted` are scopes. You
|
274
|
+
As you've probably guessed, `with_deleted` and `only_deleted` are scopes. You
|
275
|
+
can, however, chain them freely with other scopes you might have.
|
201
276
|
|
202
277
|
For example:
|
203
278
|
|
@@ -216,10 +291,10 @@ You can work freely with scopes and it will just work:
|
|
216
291
|
```ruby
|
217
292
|
class Paranoiac < ActiveRecord::Base
|
218
293
|
acts_as_paranoid
|
219
|
-
scope :pretty, where(:
|
294
|
+
scope :pretty, where(pretty: true)
|
220
295
|
end
|
221
296
|
|
222
|
-
Paranoiac.create(:
|
297
|
+
Paranoiac.create(pretty: true)
|
223
298
|
|
224
299
|
Paranoiac.pretty.count #=> 1
|
225
300
|
Paranoiac.only_deleted.count #=> 0
|
@@ -236,11 +311,13 @@ Paranoiac.pretty.only_deleted.count #=> 1
|
|
236
311
|
|
237
312
|
Associations are also supported.
|
238
313
|
|
239
|
-
From the simplest behaviors you'd expect to more nifty things like the ones
|
314
|
+
From the simplest behaviors you'd expect to more nifty things like the ones
|
315
|
+
mentioned previously or the usage of the `:with_deleted` option with
|
316
|
+
`belongs_to`
|
240
317
|
|
241
318
|
```ruby
|
242
319
|
class Parent < ActiveRecord::Base
|
243
|
-
has_many :children, :
|
320
|
+
has_many :children, class_name: "ParanoiacChild"
|
244
321
|
end
|
245
322
|
|
246
323
|
class ParanoiacChild < ActiveRecord::Base
|
@@ -248,7 +325,8 @@ class ParanoiacChild < ActiveRecord::Base
|
|
248
325
|
belongs_to :parent
|
249
326
|
|
250
327
|
# You may need to provide a foreign_key like this
|
251
|
-
belongs_to :parent_including_deleted, :
|
328
|
+
belongs_to :parent_including_deleted, class_name: "Parent",
|
329
|
+
foreign_key: 'parent_id', with_deleted: true
|
252
330
|
end
|
253
331
|
|
254
332
|
parent = Parent.first
|
@@ -259,19 +337,38 @@ child.parent #=> nil
|
|
259
337
|
child.parent_including_deleted #=> Parent (it works!)
|
260
338
|
```
|
261
339
|
|
340
|
+
### Callbacks
|
341
|
+
|
342
|
+
There are couple of callbacks that you may use when dealing with deletion and
|
343
|
+
recovery of objects. There is `before_recover` and `after_recover` which will
|
344
|
+
be triggered before and after the recovery of an object respectively.
|
345
|
+
|
346
|
+
Default ActiveRecord callbacks such as `before_destroy` and `after_destroy` will
|
347
|
+
be triggered around `.destroy!` and `.destroy_fully!`.
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
class Paranoiac < ActiveRecord::Base
|
351
|
+
acts_as_paranoid
|
352
|
+
|
353
|
+
before_recover :set_counts
|
354
|
+
after_recover :update_logs
|
355
|
+
end
|
356
|
+
```
|
357
|
+
|
262
358
|
## Caveats
|
263
359
|
|
264
360
|
Watch out for these caveats:
|
265
361
|
|
266
|
-
|
267
|
-
-
|
268
|
-
|
269
|
-
|
270
|
-
-
|
362
|
+
- You cannot use scopes named `with_deleted` and `only_deleted`
|
363
|
+
- You cannot use scopes named `deleted_inside_time_window`,
|
364
|
+
`deleted_before_time`, `deleted_after_time` **if** your paranoid column's
|
365
|
+
type is `time`
|
366
|
+
- You cannot name association `*_with_deleted`
|
367
|
+
- `unscoped` will return all records, deleted or not
|
271
368
|
|
272
369
|
# Acknowledgements
|
273
370
|
|
274
|
-
* To [Rick Olson](https://github.com/technoweenie) for creating acts_as_paranoid
|
371
|
+
* To [Rick Olson](https://github.com/technoweenie) for creating `acts_as_paranoid`
|
275
372
|
* To [cheerfulstoic](https://github.com/cheerfulstoic) for adding recursive recovery
|
276
373
|
* To [Jonathan Vaught](https://github.com/gravelpup) for adding paranoid validations
|
277
374
|
* To [Geoffrey Hichborn](https://github.com/phene) for improving the overral code quality and adding support for after_commit
|
@@ -283,5 +380,6 @@ Watch out for these caveats:
|
|
283
380
|
* To [Jean Boussier](https://github.com/byroot) for initial Rails 4.0.0 support
|
284
381
|
* To [Matijs van Zuijlen](https://github.com/mvz) for Rails 4.1 and 4.2 support
|
285
382
|
* To [Andrey Ponomarenko](https://github.com/sjke) for Rails 5 support
|
383
|
+
* To [Daniel Rice](https://github.com/danielricecodes), [Josh Bryant](https://github.com/jbryant92), and [Romain Alexandre](https://github.com/RomainAlexandre) for Rails 6.0 support.
|
286
384
|
|
287
385
|
See `LICENSE`.
|