Validate Before Delete


#1

I have an Order model with a ‘status’ column. What I want to be able to
do
is validate that the status of the Order is not completed before it is
allowed to be deleted. I tried the following method in my Model, but it
appears that this only works for an :update or :create on the record.
Anyone know how to do this, and if it should be in the model or the
controller?

validates_each :approval_status do |record, attr, value|
  record.errors.add attr, 'Order Is Completed' if value == 

“Completed”
end


#2

On 5/16/06, Davy C. removed_email_address@domain.invalid wrote:

I have an Order model with a ‘status’ column. What I want to be able to do
is validate that the status of the Order is not completed before it is
allowed to be deleted. I tried the following method in my Model, but it
appears that this only works for an :update or :create on the record.
Anyone know how to do this, and if it should be in the model or the
controller?

validates_each :approval_status do |record, attr, value|
  record.errors.add attr, 'Order Is Completed' if value == "Completed"
end

Look at the before_destroy ActiveRecord callback. Moving your delete
validation into a callback in your model and returning false on error
should give you the desired results.

cheers,
Ben

http://teamaskins.net


#3

Yep, use before_destroy to add an error and return false.

def before_destroy
if approval_status == ‘Completed’
errors.add “Order Is Completed”
false
end
end

One thing to be aware of is the order in which AR callbacks are
called. The docs say:

“”“Callbacks are generally run in the order they are defined, with
the exception of callbacks defined as methods on the model, which are
called last.”""

If you are halting the destroy action with before_destroy, it is
possible that associations specified as :dependent will be deleted
before the before_destroy method is called. That is officially a Bad
Thing. To make sure it doesn’t happen, specify the before_destroy
callback inline BEFORE any dependent associations:

class Person < ActiveRecord::Base
before_destroy do |person|
if person.approval_status == ‘Completed’
person.errors.add “Order Is Completed”
false
end
end

has_many … :dependent => …
end

Cheers, Jonathan.