在Rails中 - 使用has_many的效果是什么:通过has_and_belongs_to_many? 考虑使用两个模型 - 具有多对多关系的帖子和标签,如下所示:
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.tags
和tag.posts
的正确结果 - 其中{ {1}}和post
分别指代tag
和Post
模型的实例。
这是正确的用法还是有任何我不知道的副作用?另外,如果它是正确的,这是Rails实现这个目标的方法吗?
谢谢!
答案 0 :(得分:2)
仅在设置多对多关联时使用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不能总是完全适合英语。您需要post_tag_id
上的post
列,而belongs_to
则需要这一列。另一方面,has_one
会在其他一侧出现名为post_id
的列,即post_tag
。但这是不可能的,因为post_tag
有很多posts
(不仅仅是一个),因此post
ID无法保存在post_tags
中。
<强>更新强>:
关联之间的区别仅在于您提供的方法和可以传递的选项(Rails指南中关于关联的解释)。例如,has_one
和belongs_to
具有相同的方法:
association(force_reload = false)
association=(associate)
build_association(attributes = {})
create_association(attributes = {})
但是,例如,方法association=
和create_association
意味着外键应该在哪里(就像我上面解释的那样)。
has_and_belongs_to_many
和has_many
的方法可能没有任何不同,但它们可以通过的选项不同。例如,您可以传入
:dependent => :destroy
<{1>}关联上的,但你无法将其传递给has_many
,因为这意味着没有多大意义,因为它意味着多对多关联;如果父记录被销毁,子记录仍然可以与其他记录连接,因此它们也不应被销毁。
答案 1 :(得分:1)
虽然我不确定在关系的一侧有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
保持其他关系不变。