Without knowing more of the logic of your app, I think that frozen? is your best bet.
Failing that, you could certainly add a "destroyed" attribute to your models that you trigger in the callbacks and that could be checked against if you want a more precise solution.
destroying an object doesn't return anything other than a call to freeze (as far as I know) so I think frozen? is your best bet. Your other option is to rescue from ActiveRecord::RecordNotFound if you did something like record.reload.
I think Mike's tactic above could be best, or you could write a wrapper for these cases mentioned if you want to start 'making assumptions'.
This is coming very soon. In the latest Riding Rails post, it says this:
And finally, it's not necessarily
BugMash-related, but José Valim -
among dozens of other commits - added
model.destroyed?. This nifty method
will return true only if the instance
you're currently looking at has been
successfully destroyed.
While record.destroyed? works fine, and does return true or false, you can also DRY this up a little bit and create the if condition on the line you call destroy on in your controller.
record = Object.find(params[:id])
if record.destroy
... happy path
else
... sad path
end
Realize this post is a bit late in the game. But should anyone want to discuss this more, i'm game!
Side note: I also had an after_destroy validation on my model and while it worked, a separate method for something like this seems like overkill ;)
record.destroyed?
# or...
Record.exists?(record) # also very fast!
You'd think that record.destroyed? is better because it doesn't send an extra database request but actually Record.exists? is so extremely fast, that this typically isn't a reason to prefer one over the other.
# Assuming no issues when destroying the record...
x = record_one.destroy
x.destroyed? # Would return false! (even though the record no longer exists in the db)
Record.exists?(x) # Would correctly return false
# vs.
record_two.destroy
record_two.destroyed? # Would correctly return true
Record.exists?(record_two) # Would correctly return false
If you're in a controller, destroy! will throw a ActiveRecord::RecordNotDestroyed, which you can catch, based on before_destroy callbacks.
def destroy
render json: @record.destroy!
rescue ActiveRecord::RecordNotDestroyed
# @record will work fine down here, it still exists.
render json: { errors: ["Record not destroyed"] }
end