acts_as_paranoid 0.5.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +117 -0
- data/LICENSE +1 -1
- data/README.md +175 -50
- data/lib/acts_as_paranoid.rb +34 -31
- data/lib/acts_as_paranoid/associations.rb +28 -17
- data/lib/acts_as_paranoid/core.rb +144 -53
- data/lib/acts_as_paranoid/relation.rb +2 -0
- data/lib/acts_as_paranoid/validations.rb +8 -65
- data/lib/acts_as_paranoid/version.rb +3 -1
- data/test/test_associations.rb +161 -39
- data/test/test_core.rb +252 -55
- data/test/test_default_scopes.rb +38 -37
- data/test/test_helper.rb +136 -67
- data/test/test_inheritance.rb +5 -3
- data/test/test_relations.rb +29 -21
- data/test/test_validations.rb +10 -7
- metadata +80 -30
- data/lib/acts_as_paranoid/preloader_association.rb +0 -15
- data/test/test_preloader_association.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a57d617e3e2f52608fefad1c84bba5d6825d1b9ea96e681ade8739461ef35796
|
4
|
+
data.tar.gz: 549ef0573150ba7f30740a6145cb6b52ef2916b3584199fc0bab8eba17271eb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13ac9918fc0dc45e93d02ad799f20fe9c13afd4eba4a0b81c52201bc495a690dc80b1ab9ba9e700b7d072a61c5973dcf8d134a1049c581d61c1c0120f4444d59
|
7
|
+
data.tar.gz: 6bba5d24a72d45b5de90670e1c577d6172160d1ee5d3850a3d9dd3845eb2fd73060a6d441d738b99dc9aea516189a6807c0406f377997dddf8ac443f88db6fbd
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
Notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
## 0.7.0
|
6
|
+
|
7
|
+
### Breaking changes
|
8
|
+
|
9
|
+
* Support Rails 5.2+ only ([#126], by [Daniel Rice][danielricecodes])
|
10
|
+
* Update set of supported rubies to 2.4-2.7 ([#144], [#173] by [Matijs van Zuijlen][mvz])
|
11
|
+
|
12
|
+
### Improvements
|
13
|
+
|
14
|
+
* Handle `with_deleted` association option as a scope ([#147], by [Matijs van Zuijlen][mvz])
|
15
|
+
* Simplify validation override ([#158], by [Matijs van Zuijlen][mvz])
|
16
|
+
* Use correct unscope syntax so unscope works on Rails Edge ([#160],
|
17
|
+
by [Matijs van Zuijlen][mvz])
|
18
|
+
* Fix ruby 2.7 keyword argument deprecation warning ([#161], by [Jon Riddle][wtfspm])
|
19
|
+
|
20
|
+
### Documentation
|
21
|
+
|
22
|
+
* Document save after destroy behavior ([#146], by [Matijs van Zuijlen][mvz])
|
23
|
+
* Update version number instructions for installing gem ([#164],
|
24
|
+
by [Kevin McAlear][kevinmcalear])
|
25
|
+
* Add example with `destroyed_fully?` and `deleted_fully?` to the readme ([#170],
|
26
|
+
by [Kiril Mitov][thebravoman])
|
27
|
+
|
28
|
+
### Internal
|
29
|
+
|
30
|
+
* Improve code quality using RuboCop ([#148], [#152], [#159], [#163], [#171] and [#173],
|
31
|
+
by [Matijs van Zuijlen][mvz])
|
32
|
+
* Measure code coverage using SimpleCov ([#150] and [#175] by [Matijs van Zuijlen][mvz])
|
33
|
+
* Silence warnings emitted during tests ([#156], by [Matijs van Zuijlen][mvz])
|
34
|
+
* Make rake tasks more robust and intuitive ([#157], by [Matijs van Zuijlen][mvz])
|
35
|
+
|
36
|
+
## 0.6.3
|
37
|
+
|
38
|
+
* Update Travis CI configuration ([#137], by [Matijs van Zuijlen][mvz])
|
39
|
+
* Add predicate to check if record was soft deleted or hard deleted ([#136],
|
40
|
+
by [Aymeric Le Dorze][aymeric-ledorze])
|
41
|
+
* Add support for recover! method ([#75], by [vinoth][avinoth])
|
42
|
+
* Fix a record being dirty after destroying it ([#135], by
|
43
|
+
[Aymeric Le Dorze][aymeric-ledorze])
|
44
|
+
|
45
|
+
## 0.6.2
|
46
|
+
|
47
|
+
* Prevent recovery of non-deleted records
|
48
|
+
([#133], by [Mary Beliveau][marycodes2] and [Valerie Woolard][valeriecodes])
|
49
|
+
* Allow model to set `table_name` after `acts_as_paranoid` macro
|
50
|
+
([#131], by [Alex Wheeler][AlexWheeler])
|
51
|
+
* Make counter cache work with a custom column name and with optional
|
52
|
+
associations ([#123], by [Ned Campion][nedcampion])
|
53
|
+
|
54
|
+
## 0.6.1
|
55
|
+
|
56
|
+
* Add support for Rails 6 ([#124], by [Daniel Rice][danielricecodes],
|
57
|
+
[Josh Bryant][jbryant92], and [Romain Alexandre][RomainAlexandre])
|
58
|
+
* Add support for incrementing and decrementing counter cache columns on
|
59
|
+
associated objects ([#119], by [Dimitar Lukanov][shadydealer])
|
60
|
+
* Add `:double_tap_destroys_fully` option, with default `true` ([#116],
|
61
|
+
by [Michael Riviera][ri4a])
|
62
|
+
* Officially support Ruby 2.6 ([#114], by [Matijs van Zuijlen][mvz])
|
63
|
+
|
64
|
+
## 0.6.0 and earlier
|
65
|
+
|
66
|
+
(To be added)
|
67
|
+
|
68
|
+
<!-- Contributors -->
|
69
|
+
|
70
|
+
[AlexWheeler]: https://github.com/AlexWheeler
|
71
|
+
[RomainAlexandre]: https://github.com/RomainAlexandre
|
72
|
+
[avinoth]: https://github.com/avinoth
|
73
|
+
[aymeric-ledorze]: https://github.com/aymeric-ledorze
|
74
|
+
[danielricecodes]: https://github.com/danielricecodes
|
75
|
+
[jbryant92]: https://github.com/jbryant92
|
76
|
+
[kevinmcalear]: https://github.com/kevinmcalear
|
77
|
+
[marycodes2]: https://github.com/marycodes2
|
78
|
+
[mvz]: https://github.com/mvz
|
79
|
+
[nedcampion]: https://github.com/nedcampion
|
80
|
+
[ri4a]: https://github.com/ri4a
|
81
|
+
[shadydealer]: https://github.com/shadydealer
|
82
|
+
[thebravoman]: https://github.com/thebravoman
|
83
|
+
[valeriecodes]: https://github.com/valeriecodes
|
84
|
+
[wtfspm]: https://github.com/wtfspm
|
85
|
+
|
86
|
+
<!-- issues & pull requests -->
|
87
|
+
|
88
|
+
[#175]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/175
|
89
|
+
[#173]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/173
|
90
|
+
[#171]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/171
|
91
|
+
[#170]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/170
|
92
|
+
[#164]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/164
|
93
|
+
[#163]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/163
|
94
|
+
[#161]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/161
|
95
|
+
[#160]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/160
|
96
|
+
[#159]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/159
|
97
|
+
[#158]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/158
|
98
|
+
[#157]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/157
|
99
|
+
[#156]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/156
|
100
|
+
[#152]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/152
|
101
|
+
[#150]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/150
|
102
|
+
[#148]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/148
|
103
|
+
[#147]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/147
|
104
|
+
[#146]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/146
|
105
|
+
[#144]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/144
|
106
|
+
[#137]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/137
|
107
|
+
[#136]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/136
|
108
|
+
[#135]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/135
|
109
|
+
[#133]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/133
|
110
|
+
[#131]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/131
|
111
|
+
[#126]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/126
|
112
|
+
[#124]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/124
|
113
|
+
[#123]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/123
|
114
|
+
[#119]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/119
|
115
|
+
[#116]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/116
|
116
|
+
[#114]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/114
|
117
|
+
[#75]: https://github.com/ActsAsParanoid/acts_as_paranoid/pull/75
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -4,17 +4,43 @@
|
|
4
4
|
|
5
5
|
A Rails plugin to add soft delete.
|
6
6
|
|
7
|
-
This gem can be used to hide records instead of deleting them, making them
|
7
|
+
This gem can be used to hide records instead of deleting them, making them
|
8
|
+
recoverable later.
|
8
9
|
|
9
10
|
## Support
|
10
11
|
|
11
|
-
**This branch targets Rails
|
12
|
+
**This branch targets Rails 5.2+ and Ruby 2.4+ only**
|
12
13
|
|
13
|
-
If you're working with
|
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.
|
17
|
+
|
18
|
+
### Known issues
|
19
|
+
|
20
|
+
* Using `acts_as_paranoid` and ActiveStorage on the same model
|
21
|
+
[leads to a SystemStackError](https://github.com/ActsAsParanoid/acts_as_paranoid/issues/103).
|
22
|
+
* You cannot directly create a model in a deleted state, or update a model
|
23
|
+
after it's been deleted.
|
14
24
|
|
15
25
|
## Usage
|
16
26
|
|
17
|
-
|
27
|
+
#### Install gem:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
gem 'acts_as_paranoid', '~> 0.7.0'
|
31
|
+
```
|
32
|
+
|
33
|
+
```shell
|
34
|
+
bundle install
|
35
|
+
```
|
36
|
+
|
37
|
+
#### Create migration
|
38
|
+
|
39
|
+
```shell
|
40
|
+
bin/rails generate migration AddDeletedAtToParanoiac deleted_at:datetime:index
|
41
|
+
```
|
42
|
+
|
43
|
+
#### Enable ActsAsParanoid
|
18
44
|
|
19
45
|
```ruby
|
20
46
|
class Paranoiac < ActiveRecord::Base
|
@@ -22,26 +48,42 @@ class Paranoiac < ActiveRecord::Base
|
|
22
48
|
end
|
23
49
|
```
|
24
50
|
|
51
|
+
By default, ActsAsParanoid assumes a record's *deletion* is stored in a
|
52
|
+
`datetime` column called `deleted_at`.
|
53
|
+
|
25
54
|
### Options
|
26
55
|
|
27
|
-
|
56
|
+
If you are using a different column name and type to store a record's
|
57
|
+
*deletion*, you can specify them as follows:
|
28
58
|
|
29
|
-
-
|
30
|
-
-
|
59
|
+
- `column: 'deleted'`
|
60
|
+
- `column_type: 'boolean'`
|
31
61
|
|
32
|
-
|
62
|
+
While *column* can be anything (as long as it exists in your database), *type*
|
63
|
+
is restricted to:
|
33
64
|
|
34
65
|
- `boolean`
|
35
66
|
- `time` or
|
36
67
|
- `string`
|
37
68
|
|
38
|
-
|
69
|
+
Note that the `time` type corresponds to the database column type `datetime`
|
70
|
+
in your Rails migrations and schema.
|
39
71
|
|
40
|
-
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.
|
41
82
|
|
42
83
|
### Filtering
|
43
84
|
|
44
|
-
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.
|
45
87
|
|
46
88
|
So, `Paranoiac.all` will **not** include the **deleted records**.
|
47
89
|
|
@@ -52,7 +94,8 @@ Paranoiac.only_deleted # retrieves only the deleted records
|
|
52
94
|
Paranoiac.with_deleted # retrieves all records, deleted or not
|
53
95
|
```
|
54
96
|
|
55
|
-
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:
|
56
99
|
|
57
100
|
```ruby
|
58
101
|
time = Time.now
|
@@ -69,24 +112,36 @@ Paranoiac.deleted_inside_time_window(time, 2.minutes)
|
|
69
112
|
In order to really delete a record, just use:
|
70
113
|
|
71
114
|
```ruby
|
72
|
-
paranoiac.
|
115
|
+
paranoiac.destroy_fully!
|
73
116
|
Paranoiac.delete_all!(conditions)
|
74
117
|
```
|
75
118
|
|
76
|
-
|
119
|
+
**NOTE:** The `.destroy!` method is still usable, but equivalent to `.destroy`.
|
120
|
+
It just hides the object.
|
77
121
|
|
78
|
-
Alternatively you can permanently delete a record by calling `destroy` or
|
122
|
+
Alternatively you can permanently delete a record by calling `destroy` or
|
123
|
+
`delete_all` on the object **twice**.
|
79
124
|
|
80
|
-
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.
|
81
127
|
|
82
128
|
Take this example:
|
83
129
|
|
84
130
|
```ruby
|
85
131
|
p = Paranoiac.first
|
86
|
-
|
87
|
-
|
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
|
88
138
|
```
|
89
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
|
+
|
90
145
|
### Recovery
|
91
146
|
|
92
147
|
Recovery is easy. Just invoke `recover` on it, like this:
|
@@ -95,53 +150,82 @@ Recovery is easy. Just invoke `recover` on it, like this:
|
|
95
150
|
Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover
|
96
151
|
```
|
97
152
|
|
98
|
-
All associations marked as
|
153
|
+
All associations marked as `dependent: :destroy` are also recursively recovered.
|
99
154
|
|
100
|
-
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:
|
101
157
|
|
102
158
|
```ruby
|
103
|
-
Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover(:
|
159
|
+
Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover(recursive: false)
|
104
160
|
```
|
105
161
|
|
106
|
-
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
|
107
164
|
|
108
165
|
```ruby
|
109
166
|
class Paranoiac < ActiveRecord::Base
|
110
|
-
|
167
|
+
acts_as_paranoid recover_dependent_associations: false
|
111
168
|
end
|
112
169
|
```
|
113
170
|
|
114
|
-
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.
|
115
173
|
|
116
|
-
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.
|
117
176
|
|
118
|
-
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.
|
119
179
|
|
120
180
|
This window can be changed with the `dependent_recovery_window` option:
|
121
181
|
|
122
182
|
```ruby
|
123
183
|
class Paranoiac < ActiveRecord::Base
|
124
|
-
|
125
|
-
|
184
|
+
acts_as_paranoid
|
185
|
+
has_many :paranoids, dependent: :destroy
|
126
186
|
end
|
127
187
|
|
128
188
|
class Paranoid < ActiveRecord::Base
|
129
|
-
|
189
|
+
belongs_to :paranoic
|
130
190
|
|
131
|
-
|
132
|
-
|
133
|
-
|
191
|
+
# Paranoid objects will be recovered alongside Paranoic objects
|
192
|
+
# if they were deleted within 10 minutes of the Paranoic object
|
193
|
+
acts_as_paranoid dependent_recovery_window: 10.minutes
|
134
194
|
end
|
135
195
|
```
|
136
196
|
|
137
197
|
or in the recover statement
|
138
198
|
|
139
199
|
```ruby
|
140
|
-
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)
|
141
219
|
```
|
142
220
|
|
143
221
|
### Validation
|
144
|
-
|
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.
|
145
229
|
|
146
230
|
```ruby
|
147
231
|
class Paranoiac < ActiveRecord::Base
|
@@ -150,10 +234,10 @@ class Paranoiac < ActiveRecord::Base
|
|
150
234
|
validates_uniqueness_of_without_deleted :name
|
151
235
|
end
|
152
236
|
|
153
|
-
p1 = Paranoiac.create(:
|
237
|
+
p1 = Paranoiac.create(name: 'foo')
|
154
238
|
p1.destroy
|
155
239
|
|
156
|
-
p2 = Paranoiac.new(:
|
240
|
+
p2 = Paranoiac.new(name: 'foo')
|
157
241
|
p2.valid? #=> true
|
158
242
|
p2.save
|
159
243
|
|
@@ -161,16 +245,34 @@ p1.recover #=> fails validation!
|
|
161
245
|
```
|
162
246
|
|
163
247
|
### Status
|
164
|
-
|
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?.
|
165
261
|
|
166
262
|
```ruby
|
167
|
-
Paranoiac.create(:
|
263
|
+
Paranoiac.create(name: 'foo').destroy
|
168
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
|
169
270
|
```
|
170
271
|
|
171
272
|
### Scopes
|
172
273
|
|
173
|
-
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.
|
174
276
|
|
175
277
|
For example:
|
176
278
|
|
@@ -189,10 +291,10 @@ You can work freely with scopes and it will just work:
|
|
189
291
|
```ruby
|
190
292
|
class Paranoiac < ActiveRecord::Base
|
191
293
|
acts_as_paranoid
|
192
|
-
scope :pretty, where(:
|
294
|
+
scope :pretty, where(pretty: true)
|
193
295
|
end
|
194
296
|
|
195
|
-
Paranoiac.create(:
|
297
|
+
Paranoiac.create(pretty: true)
|
196
298
|
|
197
299
|
Paranoiac.pretty.count #=> 1
|
198
300
|
Paranoiac.only_deleted.count #=> 0
|
@@ -209,11 +311,13 @@ Paranoiac.pretty.only_deleted.count #=> 1
|
|
209
311
|
|
210
312
|
Associations are also supported.
|
211
313
|
|
212
|
-
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`
|
213
317
|
|
214
318
|
```ruby
|
215
319
|
class Parent < ActiveRecord::Base
|
216
|
-
has_many :children, :
|
320
|
+
has_many :children, class_name: "ParanoiacChild"
|
217
321
|
end
|
218
322
|
|
219
323
|
class ParanoiacChild < ActiveRecord::Base
|
@@ -221,7 +325,8 @@ class ParanoiacChild < ActiveRecord::Base
|
|
221
325
|
belongs_to :parent
|
222
326
|
|
223
327
|
# You may need to provide a foreign_key like this
|
224
|
-
belongs_to :parent_including_deleted, :
|
328
|
+
belongs_to :parent_including_deleted, class_name: "Parent",
|
329
|
+
foreign_key: 'parent_id', with_deleted: true
|
225
330
|
end
|
226
331
|
|
227
332
|
parent = Parent.first
|
@@ -232,19 +337,38 @@ child.parent #=> nil
|
|
232
337
|
child.parent_including_deleted #=> Parent (it works!)
|
233
338
|
```
|
234
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
|
+
|
235
358
|
## Caveats
|
236
359
|
|
237
360
|
Watch out for these caveats:
|
238
361
|
|
239
|
-
|
240
|
-
-
|
241
|
-
|
242
|
-
|
243
|
-
-
|
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
|
244
368
|
|
245
369
|
# Acknowledgements
|
246
370
|
|
247
|
-
* 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`
|
248
372
|
* To [cheerfulstoic](https://github.com/cheerfulstoic) for adding recursive recovery
|
249
373
|
* To [Jonathan Vaught](https://github.com/gravelpup) for adding paranoid validations
|
250
374
|
* To [Geoffrey Hichborn](https://github.com/phene) for improving the overral code quality and adding support for after_commit
|
@@ -256,5 +380,6 @@ Watch out for these caveats:
|
|
256
380
|
* To [Jean Boussier](https://github.com/byroot) for initial Rails 4.0.0 support
|
257
381
|
* To [Matijs van Zuijlen](https://github.com/mvz) for Rails 4.1 and 4.2 support
|
258
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.
|
259
384
|
|
260
385
|
See `LICENSE`.
|