Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
paranoia
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ikcrm_common
paranoia
Commits
103c33b0
Commit
103c33b0
authored
Feb 20, 2017
by
Ben A. Morgan
Committed by
GitHub
Feb 20, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #383 from netguru-hackathon/core
Add recovery window feature
parents
ba48f196
4551c3b2
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
6 deletions
+61
-6
README.md
+8
-0
lib/paranoia.rb
+21
-6
test/paranoia_test.rb
+32
-0
No files found.
README.md
View file @
103c33b0
...
@@ -181,6 +181,14 @@ Client.restore(id, :recursive => true)
...
@@ -181,6 +181,14 @@ Client.restore(id, :recursive => true)
client
.
restore
(
:recursive
=>
true
)
client
.
restore
(
:recursive
=>
true
)
```
```
If you want to restore a record and only those dependently destroyed associated records that were deleted within 2 minutes of the object upon which they depend:
```
ruby
Client
.
restore
(
id
,
:recursive
=>
true
.
:recovery_window
=>
2
.
minutes
)
# or
client
.
restore
(
:recursive
=>
true
,
:recovery_window
=>
2
.
minutes
)
```
For more information, please look at the tests.
For more information, please look at the tests.
#### About indexes:
#### About indexes:
...
...
lib/paranoia.rb
View file @
103c33b0
...
@@ -105,14 +105,15 @@ module Paranoia
...
@@ -105,14 +105,15 @@ module Paranoia
def
restore!
(
opts
=
{})
def
restore!
(
opts
=
{})
self
.
class
.
transaction
do
self
.
class
.
transaction
do
run_callbacks
(
:restore
)
do
run_callbacks
(
:restore
)
do
recovery_window_range
=
get_recovery_window_range
(
opts
)
# Fixes a bug where the build would error because attributes were frozen.
# Fixes a bug where the build would error because attributes were frozen.
# This only happened on Rails versions earlier than 4.1.
# This only happened on Rails versions earlier than 4.1.
noop_if_frozen
=
ActiveRecord
.
version
<
Gem
::
Version
.
new
(
"4.1"
)
noop_if_frozen
=
ActiveRecord
.
version
<
Gem
::
Version
.
new
(
"4.1"
)
if
(
noop_if_frozen
&&
!
@attributes
.
frozen?
)
||
!
noop_if_frozen
if
within_recovery_window?
(
recovery_window_range
)
&&
((
noop_if_frozen
&&
!
@attributes
.
frozen?
)
||
!
noop_if_frozen
)
write_attribute
paranoia_column
,
paranoia_sentinel_value
write_attribute
paranoia_column
,
paranoia_sentinel_value
update_columns
(
paranoia_restore_attributes
)
update_columns
(
paranoia_restore_attributes
)
end
end
restore_associated_records
if
opts
[
:recursive
]
restore_associated_records
(
recovery_window_range
)
if
opts
[
:recursive
]
end
end
end
end
...
@@ -120,6 +121,17 @@ module Paranoia
...
@@ -120,6 +121,17 @@ module Paranoia
end
end
alias
:restore
:restore!
alias
:restore
:restore!
def
get_recovery_window_range
(
opts
)
return
opts
[
:recovery_window_range
]
if
opts
[
:recovery_window_range
]
return
unless
opts
[
:recovery_window
]
(
deleted_at
-
opts
[
:recovery_window
]
..
deleted_at
+
opts
[
:recovery_window
])
end
def
within_recovery_window?
(
recovery_window_range
)
return
true
unless
recovery_window_range
recovery_window_range
.
cover?
(
deleted_at
)
end
def
paranoia_destroyed?
def
paranoia_destroyed?
send
(
paranoia_column
)
!=
paranoia_sentinel_value
send
(
paranoia_column
)
!=
paranoia_sentinel_value
end
end
...
@@ -169,7 +181,7 @@ module Paranoia
...
@@ -169,7 +181,7 @@ module Paranoia
# restore associated records that have been soft deleted when
# restore associated records that have been soft deleted when
# we called #destroy
# we called #destroy
def
restore_associated_records
def
restore_associated_records
(
recovery_window_range
=
nil
)
destroyed_associations
=
self
.
class
.
reflect_on_all_associations
.
select
do
|
association
|
destroyed_associations
=
self
.
class
.
reflect_on_all_associations
.
select
do
|
association
|
association
.
options
[
:dependent
]
==
:destroy
association
.
options
[
:dependent
]
==
:destroy
end
end
...
@@ -180,9 +192,11 @@ module Paranoia
...
@@ -180,9 +192,11 @@ module Paranoia
unless
association_data
.
nil?
unless
association_data
.
nil?
if
association_data
.
paranoid?
if
association_data
.
paranoid?
if
association
.
collection?
if
association
.
collection?
association_data
.
only_deleted
.
each
{
|
record
|
record
.
restore
(
:recursive
=>
true
)
}
association_data
.
only_deleted
.
each
do
|
record
|
record
.
restore
(
:recursive
=>
true
,
:recovery_window_range
=>
recovery_window_range
)
end
else
else
association_data
.
restore
(
:recursive
=>
true
)
association_data
.
restore
(
:recursive
=>
true
,
:recovery_window_range
=>
recovery_window_range
)
end
end
end
end
end
end
...
@@ -200,7 +214,8 @@ module Paranoia
...
@@ -200,7 +214,8 @@ module Paranoia
association_class
=
association_class_name
.
constantize
association_class
=
association_class_name
.
constantize
if
association_class
.
paranoid?
if
association_class
.
paranoid?
association_class
.
only_deleted
.
where
(
association_find_conditions
).
first
.
try!
(
:restore
,
recursive:
true
)
association_class
.
only_deleted
.
where
(
association_find_conditions
).
first
.
try!
(
:restore
,
recursive:
true
,
:recovery_window_range
=>
recovery_window_range
)
end
end
end
end
end
end
...
...
test/paranoia_test.rb
View file @
103c33b0
...
@@ -580,6 +580,38 @@ class ParanoiaTest < test_framework
...
@@ -580,6 +580,38 @@ class ParanoiaTest < test_framework
refute
c
.
paranoia_destroyed?
refute
c
.
paranoia_destroyed?
end
end
def
test_restore_with_associations_using_recovery_window
parent
=
ParentModel
.
create
first_child
=
parent
.
very_related_models
.
create
second_child
=
parent
.
very_related_models
.
create
parent
.
destroy
second_child
.
update
(
deleted_at:
parent
.
deleted_at
+
11
.
minutes
)
parent
.
restore!
(
:recursive
=>
true
)
assert_equal
true
,
parent
.
deleted_at
.
nil?
assert_equal
true
,
first_child
.
reload
.
deleted_at
.
nil?
assert_equal
true
,
second_child
.
reload
.
deleted_at
.
nil?
parent
.
destroy
second_child
.
update
(
deleted_at:
parent
.
deleted_at
+
11
.
minutes
)
parent
.
restore
(
:recursive
=>
true
,
:recovery_window
=>
10
.
minutes
)
assert_equal
true
,
parent
.
deleted_at
.
nil?
assert_equal
true
,
first_child
.
reload
.
deleted_at
.
nil?
assert_equal
false
,
second_child
.
reload
.
deleted_at
.
nil?
second_child
.
restore
parent
.
destroy
first_child
.
update
(
deleted_at:
parent
.
deleted_at
-
11
.
minutes
)
second_child
.
update
(
deleted_at:
parent
.
deleted_at
-
9
.
minutes
)
ParentModel
.
restore
(
parent
.
id
,
:recursive
=>
true
,
:recovery_window
=>
10
.
minutes
)
assert_equal
true
,
parent
.
reload
.
deleted_at
.
nil?
assert_equal
false
,
first_child
.
reload
.
deleted_at
.
nil?
assert_equal
true
,
second_child
.
reload
.
deleted_at
.
nil?
end
def
test_restore_with_associations
def
test_restore_with_associations
parent
=
ParentModel
.
create
parent
=
ParentModel
.
create
first_child
=
parent
.
very_related_models
.
create
first_child
=
parent
.
very_related_models
.
create
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment