检查记录是否在铁轨上被销毁

确实有

record.new_record?

检查某物是否是新的

我得看看有没有什么东西要出来了。

record = some_magic
record.destroy
record.is_destroyed? # => true

差不多吧。我知道毁灭会冻结物体,所以冻结了?但是这个任务有什么明确的内容吗?

44187 次浏览

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'.

Cheers.

You can do this.

Record.exists?(record.id)

However that will do a hit on the database which isn't always necessary. The only other solution I know is to do a callback as theIV mentioned.

attr_accessor :destroyed
after_destroy :mark_as_destroyed
def mark_as_destroyed
self.destroyed = true
end

And then check record.destroyed.

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.

So there you go. Coming soon!

Just do it:

record.destroyed?

Details are here ActiveRecord::Persistence

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 ;)

The short answer is:

  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.

Don't use the return value of record.destroy, which will always return a frozen instance of the record, whether it's deleted or not, from right before you tried to deleted it. See here: https://apidock.com/rails/v5.2.3/ActiveRecord/Persistence/destroy

# 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