I'm working in a legacy Rails app that has been diligently upgraded with each major version of Rails and we're currently on rails 5.1 and I can't get a before_destroy
to prevent the deletion if it fails a validation
I've been reading that return false
has been deprecated and we're all supposed to use throw :abort
but neither are working. I'm not getting any errors, the join record just gets deleted despite the throw
user.rb:
class User < ApplicationRecord
has_many :permission_users
has_many :permissions, through: :permission_users, dependent: :destroy
end
join model permission_user.rb:
class PermissionUser < ApplicationRecord
belongs_to :user
belongs_to :permission
before_destroy :check_before_removing!
private
def check_before_removing!
if not_valid? # condition isn't important
errors.add :base, exception.message
throw(:abort)
end
end
end
my spec:
specify "cannot have their admin permissions revoked" do
expect {
admin.permissions.delete admin_permission
}.to change { admin.permissions.count }.by(0)
end
# => expected `admin.permissions.count` to have changed by 0, but was changed by -1
There's a catch with this callback:
before_destroy callbacks should be placed before dependent: :destroy associations (or use the prepend: true option), to ensure they execute before the records are deleted by dependent: :destroy.
So please try
before_destroy :check_before_removing!, prepend: true
try to do something like this
before_destroy :check_before_removing, prepend: true
def check_before_removing
if true && some_condition
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