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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 59510a8af45d737dccea2ee97aa62553790c49a2
4
- data.tar.gz: d9b52994074e903a7b9d7f4d88f5113d37039f12
2
+ SHA256:
3
+ metadata.gz: a57d617e3e2f52608fefad1c84bba5d6825d1b9ea96e681ade8739461ef35796
4
+ data.tar.gz: 549ef0573150ba7f30740a6145cb6b52ef2916b3584199fc0bab8eba17271eb0
5
5
  SHA512:
6
- metadata.gz: 75b9853cab16dbce9e96a8976b0337e01fce18b38273e087ec68c39eae4fe3b4d2b347f1ead9f147226db2bced977eee5c4ae5a87658208737ae8ec9bd8e7d25
7
- data.tar.gz: 3f6f6a1337fe18092b37f84de3bb08740ab971fa55cb7fb9cb5d7db5551275d498079f8ba38b6cf282e069d529fb0bd32e6765fc364b71dbca23dab90e542d42
6
+ metadata.gz: 13ac9918fc0dc45e93d02ad799f20fe9c13afd4eba4a0b81c52201bc495a690dc80b1ab9ba9e700b7d072a61c5973dcf8d134a1049c581d61c1c0120f4444d59
7
+ data.tar.gz: 6bba5d24a72d45b5de90670e1c577d6172160d1ee5d3850a3d9dd3845eb2fd73060a6d441d738b99dc9aea516189a6807c0406f377997dddf8ac443f88db6fbd
@@ -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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Zachary Scott, Gonçalo Silva, Rick Olson
1
+ Copyright (c) 2014-2017 Zachary Scott, Gonçalo Silva, Rick Olson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
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 recoverable later.
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 4.x. and 5.x**
12
+ **This branch targets Rails 5.2+ and Ruby 2.4+ only**
12
13
 
13
- If you're working with another version, switch to the corresponding branch, or require an older version of the `acts_as_paranoid` gem.
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
- You can enable ActsAsParanoid like this:
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
- You can also specify the name of the column to store it's *deletion* and the type of data it holds:
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
- - `:column => 'deleted_at'`
30
- - `:column_type => 'time'`
59
+ - `column: 'deleted'`
60
+ - `column_type: 'boolean'`
31
61
 
32
- The values shown are the defaults. While *column* can be anything (as long as it exists in your database), *type* is restricted to:
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
- If your column type is a `string`, you can also specify which value to use when marking an object as deleted by passing `:deleted_value` (default is "deleted"). Any records with a non-matching value in this column will be treated normally (ie: not deleted).
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 `boolean`, it is possible to specify `allow_nulls` option which is `true` by default. When set to `false`, entities that have `false` value in this column will be considered not deleted, and those which have `true` will be considered deleted. When `true` everything that has a not-null value will be considered deleted.
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 the database.
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 are provided:
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.destroy!
115
+ paranoiac.destroy_fully!
73
116
  Paranoiac.delete_all!(conditions)
74
117
  ```
75
118
 
76
- You can also permanently delete a record by calling `destroy_fully!` on the object.
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 `delete_all` on the object **twice**.
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 again, it will be removed from the database.
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
- p.destroy # does NOT delete the first record, just hides it
87
- Paranoiac.only_deleted.where(:id => p.id).destroy # deletes the first record from the database
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 `:dependent => :destroy` are also recursively recovered.
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 `recursive` option:
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(:recursive => false)
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 the `recover_dependent_associations` option
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
- acts_as_paranoid :recover_dependent_associations => false
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 minutes of the object upon which they depend.
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 restoring other objects that were deleted earlier.
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 timestamp fields to mark deletion, which is the default behavior.
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
- acts_as_paranoid
125
- has_many :paranoids, :dependent => :destroy
184
+ acts_as_paranoid
185
+ has_many :paranoids, dependent: :destroy
126
186
  end
127
187
 
128
188
  class Paranoid < ActiveRecord::Base
129
- belongs_to :paranoic
189
+ belongs_to :paranoic
130
190
 
131
- # Paranoid objects will be recovered alongside Paranoic objects
132
- # if they were deleted within 10 minutes of the Paranoic object
133
- acts_as_paranoid :dependent_recovery_window => 10.minutes
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.recover(:recovery_window => 30.seconds)
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
- ActiveRecord's built-in uniqueness validation does not account for records deleted by ActsAsParanoid. If you want to check for uniqueness among non-deleted records only, use the macro `validates_as_paranoid` in your model. Then, instead of using `validates_uniqueness_of`, use `validates_uniqueness_of_without_deleted`. This will keep deleted records from counting against the uniqueness check.
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(:name => 'foo')
237
+ p1 = Paranoiac.create(name: 'foo')
154
238
  p1.destroy
155
239
 
156
- p2 = Paranoiac.new(:name => 'foo')
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
- You can check the status of your paranoid objects with the `deleted?` helper
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(:name => 'foo').destroy
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 can, however, chain them freely with other scopes you might have.
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(:pretty => true)
294
+ scope :pretty, where(pretty: true)
193
295
  end
194
296
 
195
- Paranoiac.create(:pretty => true)
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 mentioned previously or the usage of the `:with_deleted` option with `belongs_to`
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, :class_name => "ParanoiacChild"
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, :class_name => "Parent", :foreign_key => 'parent_id', :with_deleted => true
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
- - You cannot use scopes named `with_deleted` and `only_deleted`
241
- - You cannot use scopes named `deleted_inside_time_window`, `deleted_before_time`, `deleted_after_time` **if** your paranoid column's type is `time`
242
- - You cannot name association `*_with_deleted`
243
- - `unscoped` will return all records, deleted or not
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`.