Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The order of macro-style methods could be problematic for before_destroy callbacks #77

Closed
daviddavis opened this issue Oct 19, 2013 · 8 comments

Comments

@daviddavis
Copy link
Contributor

Due to rails/rails#3458, we may want to consider putting callbacks before associations (or maybe just before_destroy?). Take the following example.

def Person
  has_many :roles, :dependent => :destroy

  before_destroy :check_deletable

  def :check_deletable
    fail "Cannot delete super admin." if super_admin?
  end
end

This won't work as expected. Instead it will destroy a user's roles whenever destroy is called regardless if the user actually gets deleted. The fix is to list the callback first:

def Person
  before_destroy :check_deletable

  has_many :roles, :dependent => :destroy

  def :check_deletable
    fail "Cannot delete super admin." if super_admin?
  end
end

It might be a best practice to just list callbacks before associations--or just before_destroy?

EDIT: Thanks to @smudge (see below), here's a better workaround:

def Person
  has_many :roles, dependent: :destroy

  before_destroy :check_deletable, prepend: true

  def :check_deletable
    fail "Cannot delete super admin." if super_admin?
  end
end
@nickserv
Copy link
Contributor

👍

@xaviershay
Copy link

Just got bitten by this.

The behaviour is documented in "Ordering callbacks": http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

... but I still think it is broken behaviour.

@daviddavis
Copy link
Contributor Author

@xaviershay you mean broken in Rails? I think I'd agree with that.

@xaviershay
Copy link

correct, it's a non-obvious dependency between apparently unrelated declarative statements.

@bbatsov
Copy link
Collaborator

bbatsov commented May 11, 2014

@xaviershay @daviddavis I also agree that's broken in Rails. Maybe this should be discussed with someone on the Rails team?

@smudge
Copy link

smudge commented Jun 5, 2014

Just got hit by this too. HUGE gotchya. (dependent: :destroy trashes the db before before_destroy can do anything about it.)

For now I'm using before_destroy, prepend: true as a workaround, but I still feel that I've been lied to. (before_destroy should always run before any kind of destroy takes place.)

@andre-schilipack
Copy link

@smudge Nice workaround! before_destroy, prepend: true. I think it's the best way for me, right now.

I hope rails change its behavior soon.

@daviddavis
Copy link
Contributor Author

I opened a temporary fix in #110

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants