'Check if ActiveRecord object is destroyed using the .destroy() return value

I am maintaining someone's code base and they have something like this:

if @widget_part.destroy
  flash[:message] = "Error deleting widget part"
else
  flash[:message] = "Widget part destroyed successfully"
end

What does destroy return? Is it ok to test like this? The reason I'm asking is that I tried to use

flash[:message] = "Error deleting widget part : #{@widget_part.errors.inspect}"

and there are no error messages so I am confused. It gives something like

#<ActiveModel::Errors:0x00000103e118e8 @base=#<WidgetPart widget_id: 7, ..., 
  id: 67>, @messages={}>


Solution 1:[1]

As some people mentioned above, that destroy does not return a boolean value, instead it returns a frozen object. And additionally it does update the state of the instance object that you call it on. Here is how I write the controller:

@widget_part.destroy

if @widget_part.destroyed?
  flash[:success] = 'The part is destroyed'
else
  flash[:error] = 'Failed to destroy'
end

Solution 2:[2]

According to the Ruby on Rails API documentation, the destroy method will return the object that you destroyed, but in a frozen state.

When an object is frozen, no changes should be made to the object since it can no longer be persisted.

You can check if an object was destroyed using object.destroyed?.

Solution 3:[3]

Note that while #destroyed? works in the OP’s case, it only works when called on the same model instance as #destroy or #delete; it doesn’t check the database to see if the underlying record has been deleted via a different instance.

item1 = Item.take
# => #<Item:0x00000001322ed3c0

item2 = Item.find(item1.id)
# => #<Item:0x00000001116b92b8

item1.destroy
# => #<Item:0x00000001322ed3c0

item1.destroyed?
# => true

item2.destroyed?
# => false

item2.reload
# => raises ActiveRecord::RecordNotFound

If you need to check whether another process has deleted the record out from under you (e.g. by another user, or in a test where the record is deleted via a controller action), you need to call #exists? on the model class.

Item.exists?(item2.id)
# => false

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Trung Lê
Solution 2 Zajn
Solution 3 David Moles