acts_as_paranoid 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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`.