Forum: Ruby on Rails Validate Before Delete

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Davy C. (Guest)
on 2006-05-16 06:25
(Received via mailing list)
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
Ben and Kaz A. (Guest)
on 2006-05-16 07:20
(Received via mailing list)
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
Jonathan V. (Guest)
on 2006-05-16 08:23
(Received via mailing list)
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.
This topic is locked and can not be replied to.