Reputation: 26504
I am trying to implement before_destroy on a model. While I am following this before_destroy example I either receive a NameError or end up with something which doesn't do the before_destroy. What's wrong with my syntax?
class Person < ActiveRecord::Base
has_many :book_loans, :order => 'return_date desc'
has_many :books, :through => :book_loans
before_destroy
errors.add_to_base "Cannot delete borrower with loans" unless
book_loans.count == 0
end
Doesn't Compile
before_destroy
errors.add_to_base "Cannot delete borrower with loans" unless
book_loans.count == 0
Doesn't Work
def before_destroy
errors.add_to_base "Cannot delete borrower with loans" unless
book_loans.count == 0
end
Upvotes: 4
Views: 1446
Reputation: 54593
You can't add errors before_destroy
, because they won't impact the validation. You have to add the errors before the validation occurs, with e.g. before_validation
.
There are some additional callbacks, before_validation_on_create
and before_validation_on_update
. There is no on_destroy
version, though, because save
and valid?
is never called, so adding validation errors when you try to destroy something would be pointless.
In other words: your before_destroy
runs, but it doesn't affect anything, because nothing checks for validation errors when you destroy records.
Here's one take on implementing something that prevents record saving based on certain conditions.
before_destroy :require_no_book_loans
private
def require_no_book_loans
raise ActiveRecord::RecordInvalid unless book_loans.count == 0
end
You could also create your own error class and raise that.
FYI: You are supposed to pass a block to before_destroy
in your syntax error example.
before_destroy {|r|
r.errors.add_to_base "Foo" # ...
}
Upvotes: 6