Rails isn't running destroy callbacks for has_many through join model -
i have 2 ar models , third has_many :through
join model this:
class user < activerecord::base has_many :ratings has_many :movies, through: :ratings end class movie < activerecord::base has_many :ratings has_many :users, through: :ratings end class rating < activerecord::base belongs_to :user belongs_to :movie after_destroy puts 'destroyed' end end
occasionally, user want drop movie directly (without directly destroying rating). however, when do:
# puts user.movie_ids # => [1,2,3] user.movie_ids = [1, 2]
the rating's after_destroy
callback isn't called, although join record deleted appropriately. if modify user model this:
class user < activerecord::base has_many :ratings has_many :movies, through: :ratings, before_remove: proc { |u, m| rating.where(movie: m, user: u).destroy_all } end
everything works fine, ugly, , rails tries delete join model second time.
how can use dependent: :destroy
strategy association, rather dependent: :delete
?
answering own question, since difficult google, , answer super counter-intuitive (although don't know ideal interface be).
first, situation described thoroughly here: https://github.com/rails/rails/issues/7618. however, specific answer buried halfway down page, , issue closed (even though still issue in current rails versions).
you can specify dependent: :destroy
these types of join model destructions, adding option has_many :through
command, this:
class user < activerecord::base has_many :ratings has_many :movies, through: :ratings, dependent: :destroy end
this counter-intuitive because in normal cases, dependent: :destroy
destroy specific association's object(s).
for example, if had has_many :ratings, dependent: :destroy
here, of user's ratings destroyed when user destroyed.
we don't want destroy specific movie objects here, because may in use other users/ratings. however, rails magically knows want destroy join record, not association record, in case.
Comments
Post a Comment