Reputation: 17321
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={}>
Upvotes: 10
Views: 9944
Reputation: 51113
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
Upvotes: 1
Reputation: 5236
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
Upvotes: 5
Reputation: 1794
If you're unsure, you can use destroyed?
method. Return value of destroy is undocumented, but it returns just freezed destroyed object (you cannot update it). It doesn't return status of destroy action.
Although generally destroying object should always succeed, you can listen for ActiveRecordError. For example Optimistic Locking can raise ActiveRecord::StaleObjectError on record destroy.
Upvotes: 6
Reputation: 4088
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?
.
Upvotes: 1