Commit 7098750c by Ryan Bigg

Merge pull request #221 from duderman/real_destroy_callback

real_destroy callback
parents 857ed343 b468111d
...@@ -94,22 +94,6 @@ If you really want it gone *gone*, call `really_destroy!`: ...@@ -94,22 +94,6 @@ If you really want it gone *gone*, call `really_destroy!`:
# => client # => client
``` ```
If you want a method to be called on destroy, simply provide a `before_destroy` callback:
``` ruby
class Client < ActiveRecord::Base
acts_as_paranoid
before_destroy :some_method
def some_method
# do stuff
end
# ...
end
```
If you want to use a column other than `deleted_at`, you can pass it as an option: If you want to use a column other than `deleted_at`, you can pass it as an option:
``` ruby ``` ruby
...@@ -180,12 +164,6 @@ Client.restore(id, :recursive => true) ...@@ -180,12 +164,6 @@ Client.restore(id, :recursive => true)
client.restore(:recursive => true) client.restore(:recursive => true)
``` ```
If you want callbacks to trigger before a restore:
``` ruby
before_restore :callback_name_goes_here
```
For more information, please look at the tests. For more information, please look at the tests.
#### About indexes: #### About indexes:
...@@ -221,6 +199,24 @@ You can replace the older `acts_as_paranoid` methods as follows: ...@@ -221,6 +199,24 @@ You can replace the older `acts_as_paranoid` methods as follows:
The `recover` method in `acts_as_paranoid` runs `update` callbacks. Paranoia's The `recover` method in `acts_as_paranoid` runs `update` callbacks. Paranoia's
`restore` method does not do this. `restore` method does not do this.
## Callbacks
Paranoia provides few callbacks. It triggers `destroy` callback when the record is marked as deleted and `real_destroy` when the record is completely removed from database. It also calls `restore` callback when record is restored via paranoia
For example if you want to index you records in some search engine you can do like this:
```ruby
class Product < ActiveRecord::Base
acts_as_paranoid
after_destroy :update_document_in_search_engine
after_restore :update_document_in_search_engine
after_real_destroy :remove_document_from_search_engine
end
```
You can use these events just like regular Rails callbacks with before, after and around hooks.
## License ## License
This gem is released under the MIT license. This gem is released under the MIT license.
...@@ -47,18 +47,20 @@ module Paranoia ...@@ -47,18 +47,20 @@ module Paranoia
module Callbacks module Callbacks
def self.extended(klazz) def self.extended(klazz)
klazz.define_callbacks :restore [:restore, :real_destroy].each do |callback_name|
klazz.define_callbacks callback_name
klazz.define_singleton_method("before_restore") do |*args, &block| klazz.define_singleton_method("before_#{callback_name}") do |*args, &block|
set_callback(:restore, :before, *args, &block) set_callback(callback_name, :before, *args, &block)
end end
klazz.define_singleton_method("around_restore") do |*args, &block| klazz.define_singleton_method("around_#{callback_name}") do |*args, &block|
set_callback(:restore, :around, *args, &block) set_callback(callback_name, :around, *args, &block)
end end
klazz.define_singleton_method("after_restore") do |*args, &block| klazz.define_singleton_method("after_#{callback_name}") do |*args, &block|
set_callback(:restore, :after, *args, &block) set_callback(callback_name, :after, *args, &block)
end
end end
end end
end end
...@@ -172,6 +174,8 @@ class ActiveRecord::Base ...@@ -172,6 +174,8 @@ class ActiveRecord::Base
alias :destroy_without_paranoia :destroy alias :destroy_without_paranoia :destroy
def really_destroy! def really_destroy!
transaction do
run_callbacks(:real_destroy) do
dependent_reflections = self.class.reflections.select do |name, reflection| dependent_reflections = self.class.reflections.select do |name, reflection|
reflection.options[:dependent] == :destroy reflection.options[:dependent] == :destroy
end end
...@@ -192,6 +196,8 @@ class ActiveRecord::Base ...@@ -192,6 +196,8 @@ class ActiveRecord::Base
write_attribute(paranoia_column, current_time_from_proper_timezone) write_attribute(paranoia_column, current_time_from_proper_timezone)
destroy_without_paranoia destroy_without_paranoia
end end
end
end
include Paranoia include Paranoia
class_attribute :paranoia_column, :paranoia_sentinel_value class_attribute :paranoia_column, :paranoia_sentinel_value
......
...@@ -453,6 +453,14 @@ class ParanoiaTest < test_framework ...@@ -453,6 +453,14 @@ class ParanoiaTest < test_framework
assert RelatedModel.unscoped.exists?(child_2.id) assert RelatedModel.unscoped.exists?(child_2.id)
end end
def test_really_destroy_behavior_for_callbacks
model = CallbackModel.new
model.save
model.really_destroy!
assert model.instance_variable_get(:@real_destroy_callback_called)
end
def test_really_delete def test_really_delete
model = ParanoidModel.new model = ParanoidModel.new
model.save model.save
...@@ -871,15 +879,16 @@ end ...@@ -871,15 +879,16 @@ end
class CallbackModel < ActiveRecord::Base class CallbackModel < ActiveRecord::Base
acts_as_paranoid acts_as_paranoid
before_destroy {|model| model.instance_variable_set :@destroy_callback_called, true } before_destroy { |model| model.instance_variable_set :@destroy_callback_called, true }
before_restore {|model| model.instance_variable_set :@restore_callback_called, true } before_restore { |model| model.instance_variable_set :@restore_callback_called, true }
before_update {|model| model.instance_variable_set :@update_callback_called, true } before_update { |model| model.instance_variable_set :@update_callback_called, true }
before_save {|model| model.instance_variable_set :@save_callback_called, true} before_save { |model| model.instance_variable_set :@save_callback_called, true}
before_real_destroy { |model| model.instance_variable_set :@real_destroy_callback_called, true }
after_destroy {|model| model.instance_variable_set :@after_destroy_callback_called, true } after_destroy { |model| model.instance_variable_set :@after_destroy_callback_called, true }
after_commit {|model| model.instance_variable_set :@after_commit_callback_called, true } after_commit { |model| model.instance_variable_set :@after_commit_callback_called, true }
validate {|model| model.instance_variable_set :@validate_called, true } validate { |model| model.instance_variable_set :@validate_called, true }
def remove_called_variables def remove_called_variables
instance_variables.each {|name| (name.to_s.end_with?('_called')) ? remove_instance_variable(name) : nil} instance_variables.each {|name| (name.to_s.end_with?('_called')) ? remove_instance_variable(name) : nil}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment