habtm relationship does not support :dependent option
Asked Answered
B

3

27

Is it true that HABTM relationships do not support the :dependent option?

class Person < ActiveRecord::Base
  has_and_belongs_to_many :posts, :dependent => :destroy
end

I am trying rails edge.

Brainsick answered 10/5, 2010 at 0:33 Comment(1)
As an exercise, I recommend reading this API part titled Deleting from associations, specially in the part What gets deleted?. That made me understand why and what's happening behind api.rubyonrails.org/classes/ActiveRecord/Associations/…Floozy
O
20

Yep, It doesn't support it. See the docs. Generally habtm is meant only for very very simple cases and if you start needing more complex things you should switch to has_many :through.

Olindaolinde answered 10/5, 2010 at 0:41 Comment(0)
B
87

If you want to keep to the simple has_and_belongs_to_many association, you could add this:

class Person < ActiveRecord::Base
  has_and_belongs_to_many :posts
  before_destroy { posts.clear }
end

Which will clear the join table of all entries of that person. Note: This only removes records from the join table, it does not destroy the posts (which makes sense if it is a bi-direction has_and_belongs_to_many because the post might be referenced by other persons).

But guessing from your names (Person and Post) I would assume that you can probably get away with a Person has_many :posts and a Post belongs_to :person in which case you can use the :dependent => :destroy on the has_many association.

Betelgeuse answered 9/2, 2012 at 7:6 Comment(6)
Could you please add how you would implement a dependent: :destroy action on a bi-directional has_and_belongs_to_many relationship which links to the same model?Tog
I'm not sure if the syntax was ever originally like this answer, but I know in rails 4 it is supposed to be before_destroy { posts.clear }Toomay
also you could use this to get the whole destroy effect after_destroy do User.find(:all, :uniq => true, :joins => :posts, :conditions => 'posts.id is NULL').each(&:destroy) end but might as well use has_many through at that point.Marche
I found that i don't need to do before_destroy { posts.clear } in rails 4.2.0 (postgresql). Rails deletes relationship by default (it doesn't delete related record, post in this example).Erato
Nice tip Faith. has_and_belongs_to_many continues to delete the associations in rails 5.0.0beta2Polemic
@Erato comment need to be an answer!Beatabeaten
O
20

Yep, It doesn't support it. See the docs. Generally habtm is meant only for very very simple cases and if you start needing more complex things you should switch to has_many :through.

Olindaolinde answered 10/5, 2010 at 0:41 Comment(0)
U
6

Try this:

class Person < ActiveRecord::Base
  has_and_belongs_to_many :posts
  before_destroy do
    posts.each { |post| post.destroy }
  end
end

You don't need to posts.clear as Rails 4.2+ handles this already.

Unstoppable answered 10/6, 2017 at 3:15 Comment(1)
This is the correct answer. Rails 4.2+ and 5+ both will destroy association table as soon as you destroy the HABTM association.Floozy

© 2022 - 2024 — McMap. All rights reserved.