has_many :通过 Rails 中的 has_and_belongs_to_many
在 Rails 中 - 使用 has_many :through 和 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 指南,发现他们很多时候都没有提到这种情况一对多关系。然而,我确实尝试了这个,并且在 Rails 中运行它没有产生任何行为,并且从我构建的小型测试数据库来看,似乎也返回了 post.tags
和 的正确结果tag.posts
- 其中 post
和 tag
引用 Post
和 Tag
模型的实例分别。
这是正确的用法还是有任何我不知道的副作用?另外,如果它是正确的,这是实现这一目标的 Rails 方法吗?
谢谢!
In Rails - what is the effect of using has_many :through with has_and_belongs_to_many?
Consider having two models - Posts and Tags which have a many-to-many relationship as indicated below:
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
The reason I use has_and_belongs_to_many
is because a tag
belongs to many posts.
I did look into the Rails Association guide and see that they don't mention this case for a many-to-many relationship. I, however, did try this and running it in Rails didn't yield any behavior and from the small test database that I built, also seemed to return the correct results for post.tags
and tag.posts
- where post
and tag
refer to an instance of the Post
and Tag
models respectively.
Is this correct usage or does it have any side affects that I am not aware of? Also, if it is correct, is this the Rails way of achieving this?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
仅当您设置多对多关联时(换句话说,当另一方也有
has_and_belongs_to_many
时),才使用has_and_belongs_to_many
。这就是这个协会的意义。您应该
注意到我使用了复数
post_tags
(因为这是正确的方式)。如果您遇到评论中的情况,则您
的
Post
模型和PostTag
模型中应该有一个。您现在可能会问:“为什么我应该使用
belongs_to :post_tag
?它不属于标签,它有一个标签。所以,我不应该使用has_one :post_tag
吗?”。起初这也是我的问题,但后来我发现 Rails 并不总是完全适合英语。您需要post
上的post_tag_id
列,而belongs_to
正是如此。另一方面,has_one
会期望名为post_id
的列出现在另一端,即您的post_tag< /代码>。但这是不可能的,因为
post_tag
有很多post
(不仅仅是一个),因此post
ID 不能保存在post_tags 中
。更新:
关联之间的区别仅在于提供的方法和可以传入的选项(Rails 关联指南中解释的选项)。例如,
has_one
和belongs_to
具有相同的方法:但是,例如,方法
association=
和create_association
意味着关于外键应该在哪里的不同事情(就像我上面解释的那样)。has_and_belongs_to_many
和has_many
的方法可能没有任何不同,但它们在您可以传递的选项方面有所不同。例如,您可以传入has_many
关联,但不能将其传递给has_and_belongs_to_many
,因为这没有意义,因为它意味着许多- 多对多关联;如果父记录被销毁,子记录仍然可以与其他记录连接,因此它们不应该也被销毁。You use
has_and_belongs_to_many
only when you're setting a many-to-many association (in other words, when the other side also hashas_and_belongs_to_many
). That is the meaning of this association.You should have
Notice that I used the plural,
post_tags
(because this is the correct way).If you have the situation like in your comment, you should have a
in your
Post
model, andin your
PostTag
model.You may ask now: "Why should I use
belongs_to :post_tag
? It doesn't belong to a tag, it has a tag. So, shouldn't I usehas_one :post_tag
?". This was also my question at first, but then I figured that it Rails cannot always perfectly suit the english language. You need thepost_tag_id
column on yourpost
, andbelongs_to
expects exactly that. On the other hand,has_one
would expect that a column namedpost_id
is present on the other side, that is in yourpost_tag
. But this would be impossible, becausepost_tag
has manyposts
(not only one), so thepost
IDs cannot be held inpost_tags
.Update:
The difference between associations are only in the methods you are provided and options you can pass in (the one explained in the Rails guide on associations). For example,
has_one
andbelongs_to
have the same methods:But, for example, methods
association=
andcreate_association
imply different things concerning where the foreign key should be (like I explained above).has_and_belongs_to_many
andhas_many
probably don't have anything different in their methods, but they differ in the options you can pass. For example, you can pass inon the
has_many
association, but you can't pass it to ahas_and_belongs_to_many
, because that wouldn't make sense, since it implies a many-to-many association; if a parent record is destroyed, child records can still be connected with other records, so they shouldn't also be destroyed.虽然我不确定在关系的一侧使用
has_many :through
和在另一侧使用has_and_belongs_to_many
的确切效果,但我确实知道正确的方法是使用反向的has_many :through
,如下所示:保持其他关系相同。
While I'm not sure of the exact effects of having a
has_many :through
on one side of a relationship and ahas_and_belongs_to_many
on the other side, I do know that the more correct way, would be to use a reversedhas_many :through
like so:Keeping the other relationships the same.