Rails - Cancel destroy on before_destroy callback
Rails wraps saves and destroys in a transaction, so a raise
in the callback would work:
class Post < ActiveRecord::Base
before_destroy :saveable?
def saveable?
if true
raise "Destroy aborted; you can't do that!"
end
end
end
Substitute true
for your condition.
Here's the abridged console output:
[1] pry(main)> Post.first.id
=> 1
[2] pry(main)> Post.first.destroy
RuntimeError: Destroy aborted; you can't do that!
[3] pry(main)> Post.first.id
=> 1
Documentation
As none of the given answers really solves the problem, but the comment above tells it - here the in form of an answer to make it easy to find:
In rails 5, instead of
before_destroy do
if self.some_condition?
return false
end
end
use
before_destroy do
if self.some_condition?
throw(:abort)
end
end
to make sure destroy is not being perfomed.
thanks to RFVoltolini's comment - this saved my day!
You should return false
.
Rails 5
"Canceling callbacks
If a before_* callback throws :abort, all the later callbacks and the associated action are cancelled."
Rails 4 and lower
"Canceling callbacks
If a before_* callback returns false, all the later callbacks and the associated action are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last."
Source