Why would ActiveRecord destroy fail silently?

I had a puzzling time today with trying to use ActiveRecord’s destroy command to delete a record. destroy returned false, and there were no messages in the record.errors.full_messages.

This is inadequate:

record = SomeModel.find(123)
record.destroy

Why? It’s like calling record.save without checking the return value.

Compare to this:

record = SomeModel.find(123)
destroyed = record.destroy
if !destroyed
  msgs = record.errors.full_messages
  # do something with msgs, like set flash
else
  # whatever to do after the destroy
end

However, if you don’t properly create a before_destroy callback, your msgs might look like {} (empty Hash)

What if your before_destroy callback looked like this:

def ok_to_delete
   some_condition # which return true or false
end

The problem with this code is that the error message is blank, so you have some pretty puzzling code.

Instead, what you can do is:

def ok_to_delete
   unless some_condition # which return true or false
     errors.add(:base, "did not destroy because of some condition")
  end
  some_condition
end

Then you’ll have an informative message when destroy returns false and you check the errors.