How do I 'validate' on destroy in rails
You can raise an exception which you then catch. Rails wraps deletes in a transaction, which helps matters.
For example:
class Booking < ActiveRecord::Base has_many :booking_payments .... def destroy raise "Cannot delete booking with payments" unless booking_payments.count == 0 # ... ok, go ahead and destroy super endend
Alternatively you can use the before_destroy callback. This callback is normally used to destroy dependent records, but you can throw an exception or add an error instead.
def before_destroy return true if booking_payments.count == 0 errors.add :base, "Cannot delete booking with payments" # or errors.add_to_base in Rails 2 false # Rails 5 throw(:abort)end
myBooking.destroy
will now return false, and myBooking.errors
will be populated on return.
just a note:
For rails 3
class Booking < ActiveRecord::Basebefore_destroy :booking_with_payments?privatedef booking_with_payments? errors.add(:base, "Cannot delete booking with payments") unless booking_payments.count == 0 errors.blank? #return false, to not destroy the element, otherwise, it will delete.end
It is what I did with Rails 5:
before_destroy do cannot_delete_with_qrcodes throw(:abort) if errors.present?enddef cannot_delete_with_qrcodes errors.add(:base, 'Cannot delete shop with qrcodes') if qrcodes.any?end