class Post < ActiveRecord::Base
has_many :posts_tags
has_many :tags, through: :posts_tags
end
class PostsTag < ActiveRecord::Base
belongs_to :post
belongs_to :tag
end
class Tag < ActiveRecord::Base
has_many :posts_tags
has_many :posts, through: :posts_tags
end
当Post被破坏时,我希望它的所有关联也被删除。我不想在PostsTag模型上运行验证。我只是想删除。
我发现在Post模型中添加一个依赖于帖子标签的关系可以按我的方式工作:has_many :posts_tags, dependent: :delete_all
。
但是,有关该主题的文档似乎建议我应该这样做:has_many :tags, through: :posts_tags, dependent: :delete_all
。当我这样做时,Tag对象被破坏,连接对象仍然存在。
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many
对于has_many,destroy将始终调用正在删除的记录的destroy方法,以便运行回调。但是,删除将根据:dependent选项指定的策略进行删除,或者如果没有给出依赖选项,则它将遵循默认策略。默认策略是:nullify(将外键设置为nil),除has_many:through外,其中默认策略为delete_all(删除连接记录,不运行其回调)。
也许我读错了,我找到的方法是正确的方法?
答案 0 :(得分:20)
您最初的想法:
has_many :posts_tags, dependent: :delete_all
正是你想要的。你 not 想要在has-many-though关联:tags
上声明这个,因为这会破坏所有相关的标签。您要删除的是关联本身 - 这是PostTag连接模型所代表的内容。
那么为什么文档说他们做了什么?您误解了文档描述的场景:
Post.find(1).destroy
Post.find(1).tags.delete
第一个电话(你的场景)将简单地破坏帖子。也就是说,除非您指定:dependent
策略,否则我建议您这样做。第二个调用是文档描述的内容。调用.tags.delete
不会(默认情况下)实际销毁标记(因为它们通过has-many-through连接),但是连接这些标记的关联连接模型。