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!`:
# => 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:
``` ruby
......@@ -180,12 +164,6 @@ Client.restore(id, :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.
#### About indexes:
......@@ -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
`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
This gem is released under the MIT license.
......@@ -47,18 +47,20 @@ module Paranoia
module Callbacks
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|
set_callback(:restore, :before, *args, &block)
end
klazz.define_singleton_method("before_#{callback_name}") do |*args, &block|
set_callback(callback_name, :before, *args, &block)
end
klazz.define_singleton_method("around_restore") do |*args, &block|
set_callback(:restore, :around, *args, &block)
end
klazz.define_singleton_method("around_#{callback_name}") do |*args, &block|
set_callback(callback_name, :around, *args, &block)
end
klazz.define_singleton_method("after_restore") do |*args, &block|
set_callback(:restore, :after, *args, &block)
klazz.define_singleton_method("after_#{callback_name}") do |*args, &block|
set_callback(callback_name, :after, *args, &block)
end
end
end
end
......@@ -172,25 +174,29 @@ class ActiveRecord::Base
alias :destroy_without_paranoia :destroy
def really_destroy!
dependent_reflections = self.class.reflections.select do |name, reflection|
reflection.options[:dependent] == :destroy
end
if dependent_reflections.any?
dependent_reflections.each do |name, reflection|
association_data = self.send(name)
# has_one association can return nil
# .paranoid? will work for both instances and classes
if association_data && association_data.paranoid?
if reflection.collection?
association_data.with_deleted.each(&:really_destroy!)
else
association_data.really_destroy!
transaction do
run_callbacks(:real_destroy) do
dependent_reflections = self.class.reflections.select do |name, reflection|
reflection.options[:dependent] == :destroy
end
if dependent_reflections.any?
dependent_reflections.each do |name, reflection|
association_data = self.send(name)
# has_one association can return nil
# .paranoid? will work for both instances and classes
if association_data && association_data.paranoid?
if reflection.collection?
association_data.with_deleted.each(&:really_destroy!)
else
association_data.really_destroy!
end
end
end
end
write_attribute(paranoia_column, current_time_from_proper_timezone)
destroy_without_paranoia
end
end
write_attribute(paranoia_column, current_time_from_proper_timezone)
destroy_without_paranoia
end
include Paranoia
......
......@@ -453,6 +453,14 @@ class ParanoiaTest < test_framework
assert RelatedModel.unscoped.exists?(child_2.id)
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
model = ParanoidModel.new
model.save
......@@ -871,15 +879,16 @@ end
class CallbackModel < ActiveRecord::Base
acts_as_paranoid
before_destroy {|model| model.instance_variable_set :@destroy_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_save {|model| model.instance_variable_set :@save_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_update { |model| model.instance_variable_set :@update_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_commit {|model| model.instance_variable_set :@after_commit_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 }
validate {|model| model.instance_variable_set :@validate_called, true }
validate { |model| model.instance_variable_set :@validate_called, true }
def remove_called_variables
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