Validations are used to ensure that only valid data is saved into your database. For example, it may be important to your application to ensure that every user provides a valid email address and mailing address. Model-level validations are the best way to ensure that only valid data is saved into your database.
Before saving an Active Record object, Rails runs your validations. If these validations produce any errors, Rails does not save the object. After Active Record has performed validations, any errors found can be accessed through the errors instance method, which returns a collection of errors.
If you return false from that before_destroy method, it will prevent the destruction.
This is a Rails 5 answer, if you return false it will give a deprecation warning: "Returning false
in Active Record and Active Model callbacks will not implicitly halt a callback chain in Rails 5.1".
def confirm_presence_of_alternate_administratorship_in_school
return if school.administrators.count(["administratorships.account_id != #{id}"]) > 0
errors[:base] << 'The school must have at least one administrator'
throw :abort
end
Returning false
from your validation method will prevent the record from getting destroyed.
Example:
def confirm_presence_of_alternate_administratorship_in_school
unless school.administrators.count(["administratorships.account_id != #{id}"]) > 0
# errors.add_to_base() is deprecated in Rails 3. Instead do...
errors.add(:base, "The school must have at least one administrator")
# this will prevent the object from getting destroyed
return false
end
end
Side note: I was having trouble with this error message not being displayed. The validation would work and the object would not be deleted, but there would be no message letting me know what happened. The reason for this was that the controller was redirecting to the index view instead of rendering the delete view (if there is an error while creating a new user for example, it will render :action => 'new'. In this case there is no delete view). When this happened, the instance variable on which the error message was set (in errors.add(:base,"message")) is actually being reset, which destroys the error in the process.
For Rails 5, returningfalse
won't halt the callback chain. You need to use throw(:abort)
belongs_to :account belongs_to :school
before_destroy :confirm_presence_of_alternate_administratorship_in_school
protected
def confirm_presence_of_alternate_administratorship_in_school
unless school.administrators.count(["administratorships.account_id != #{id}"]) > 0
errors.add_to_base "The school must have at least one administrator"
throw(:abort)
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With