2013-06-05 63 views
12
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模型上运行验证。我只想删除。正确的方法来删除has_many:通过连接记录?

我发现在帖子模型中添加一个依赖于帖子标签的关系,就像我想要的那样: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,破坏总是会调用被去除,使得回调运行结果的破坏方法。但是删除将根据依赖选项指定的策略执行删除操作,或者如果没有:依赖选项,则它将遵循默认策略。缺省策略是:nullify(将外键设置为零),(has_many:through除外),默认策略是delete_all(删除连接记录,不运行回调)。

  1. 我怎么能有默认的策略,实际使用?如果我离开:完全依赖,则根本没有记录被删除。我不能仅仅表明:依赖于has_many关系。 Rails回来并说:“依赖选项需要:destroy,:delete_all,:nullify或:restrict({})”。
  2. 如果我不指定:依赖于任何关系的,它不坏的PostsTag对象上POST_ID,因为它似乎暗示

也许我读这个错误,而我发现这种方法作品是正确的方式?

+1

如果标签被多个帖子使用会发生什么?如果一个帖子被删除,其他帖子将受到影响。 –

+0

为true,并且标签应该有'has_many:posts,通过::posts_tags'不是帖子,我会使用'has_many:posts_tags,dependent :: destroy'来删除posts_tag并保留标签。您可以使用rake任务或控制台删除孤立标签。 – rmagnum2002

+0

修复了关联,谢谢。我只是想了解文档。措辞令人困惑 – Brian

回答

17

你的原来的想法:

has_many :posts_tags, dependent: :delete_all 

正是你想要的。你做不是想要在有很多虽然协会:tags宣布这一点,因为这将摧毁所有相关的标签。你想要删除的是关联本身 - 这是PostTag联接模型所代表的。

那么为什么文档说他们做什么?你是误解的情况,该文档描述:

Post.find(1).destroy 
Post.find(1).tags.delete 

第一次调用(你的情况)只会破坏后。也就是说,除非你指定:dependent策略,正如我所建议的那样。第二个调用是文档描述的内容。调用.tags.delete不会(默认情况下)实际销毁标记(因为它们由has-many-through连接),而是关联这些标记的关联连接模型。

+0

啊,谢谢,这更有意义 – Brian

相关问题