的has_many:通过与Rails的

问题描述:

在Rails has_and_belongs_to_many - 什么是使用的has_many的效果:通过与has_and_belongs_to_many? 考虑有两种型号 - 帖子并有许多一对多的关系标签所指示如下:的has_many:通过与Rails的

class Tag < ActiveRecord::Base 
    has_many :posts_tag 
    has_and_belongs_to_many :posts 
end 

class Post < ActiveRecord::Base 
    has_many :posts_tag 
    has_many :tags, :through => posts_tag 
end 

class PostsTag < ActiveRecord::Base 
    belongs_to :tag 
    belongs_to :post 
end 

我用has_and_belongs_to_many是因为tag属于多个职位的原因。

我确实考虑了Rails Association guide,看到他们不提这种情况下,对于一个多一对多的关系。但是,我没有尝试这一点,并在Rails中运行它没有取得任何行为,从我建造的小型测试数据库,也似乎返回正确的结果为post.tagstag.posts - 在posttag是指的一个实例分别为PostTag型号。

这是正确的用法还是有任何副作用的影响,我不知道呢?另外,如果这是正确的,这是Rails实现这一目标的方式吗?

谢谢!

只有当您设置多对多关联时(换句话说,当对方也有has_and_belongs_to_many时)才使用has_and_belongs_to_many。这是这个协会的意义。

你应该有

class Tag < ActiveRecord::Base 
    has_many :posts_tags 
    has_many :posts, :through => :post_tags 
end 

class PostsTag < ActiveRecord::Base 
    belongs_to :tag 
    belongs_to :post 
end 

class Post < ActiveRecord::Base 
    has_many :posts_tags 
    has_many :tags, :through => :posts_tags 
end 

注意,我用的是复数,post_tags(因为这是正确的做法)。

如果你有一个像在您的评论的情况下,你应该有一个

belongs_to :post_tag 

Post模型,并

has_many :posts 

PostTag模型。

现在你可以问:“为什么要使用belongs_to :post_tag它不属于标签,它具有标签所以,我不应该用has_one :post_tag?。?”。这也是我的第一个问题,但后来我发现Rails并不总是完全适合英语。您需要postbelongs_to上的post_tag_id列正如期望的那样。另一方面,has_one预计在其他一侧上出现名为post_id的列,即post_tag。但这是不可能的,因为post_tag有很多posts(不只一个),所以post ID不能在post_tags中保存。

更新
仅在方法会为您提供协会之间的区别和选项,你可以通过在(一个在Rails的解释指导协会)。例如,has_onebelongs_to有相同的方法:

association(force_reload = false) 
association=(associate) 
build_association(attributes = {}) 
create_association(attributes = {}) 

但是,例如,方法association=create_association暗示关于其中的外键应该是(像我上面所解释的)不同的事情。

has_and_belongs_to_manyhas_many在他们的方法中可能没有任何不同,但他们在可以传递的选项上有所不同。例如,你可以在

:dependent => :destroy 

转嫁has_many关联,但你不能把它传递给一个has_and_belongs_to_many,因为那是没有意义的,因为它意味着许多-to-many关联;如果父记录被销毁,子记录仍然可以与其他记录连接,所以它们也不应该被销毁。

+0

是的,我想你说的部分“Rails不能总是完全适合英语”是我真正想找的东西:P 鉴于一些常见操作使用'has_many:through'和'has_and_belongs_to_many',从纯粹的教学角度来看,知道这是否有副作用会很有趣。我明白这不是使用它的正确方法。 – 2012-02-25 18:43:10

+0

看看更新。 – 2012-02-25 21:28:02

+0

谢谢!这就说得通了 :) – 2012-02-29 18:38:48

虽然我不知道的有一个关系的一侧has_many :through,而在另一侧的has_and_belongs_to_many的确切作用,我知道的比较正确的做法,是使用反向has_many :through像这样:

class Tag < ActiveRecord::Base 
    has_many :posts_tag 
    has_many :posts, :through => posts_tag 
end 

保持其他关系相同。

+0

在关系的一侧使用'has_one'和在另一侧使用'has_and_belongs_to_many'的副作用如何?例如在上面的例子中,如果我们要说每个'post'最多只能有一个'tag'。但是,'tag'属于许多'posts'。 – 2012-02-23 08:05:45

+0

在这种情况下,你的关系有点向后。标签'has_many'帖子,帖子'belongs_to'标签。 Post上会有'tag_id',只允许一个标签。 'has_and_belongs_to_many'将使用'has_many'不会使用的隐藏连接表。 – ctcherry 2012-02-23 20:43:24