如何在rails中与同一模型建立多对多关系?
例如,每个帖子都连接到很多帖子。
答案 0 :(得分:264)
答案 1 :(得分:15)
回答施蒂夫提出的问题:
用户之间的跟随者 - 关注者关系是双向循环关联的一个很好的例子。 用户可以包含多个:
以下是user.rb代码的外观:
class User < ActiveRecord::Base
# follower_follows "names" the Follow join table for accessing through the follower association
has_many :follower_follows, foreign_key: :followee_id, class_name: "Follow"
# source: :follower matches with the belong_to :follower identification in the Follow model
has_many :followers, through: :follower_follows, source: :follower
# followee_follows "names" the Follow join table for accessing through the followee association
has_many :followee_follows, foreign_key: :follower_id, class_name: "Follow"
# source: :followee matches with the belong_to :followee identification in the Follow model
has_many :followees, through: :followee_follows, source: :followee
end
以下是follow.rb的代码:
class Follow < ActiveRecord::Base
belongs_to :follower, foreign_key: "follower_id", class_name: "User"
belongs_to :followee, foreign_key: "followee_id", class_name: "User"
end
最值得注意的事项可能是user.rb中的:follower_follows
和:followee_follows
。例如,要使用磨机(非循环)关联的运行,团队可能包含多个:players
到:contracts
。这对于播放器也没有什么不同,播放器也可能有很多:teams
到:contracts
(在播放器的职业生涯中) 。但在这种情况下,只存在一个命名模型(即用户),相同地命名through:relationship(例如through: :follow
,或者,就像上面的帖子示例中所做的那样,{ {1}})会导致连接表的不同用例(或访问点)的命名冲突。创建through: :post_connections
和:follower_follows
是为了避免这种命名冲突。现在,用户可以有多个:followee_follows
到:followers
和多个:follower_follows
到:followees
。
要确定用户,请执行以下操作:跟随(在:followee_follows
调用数据库时),Rails现在可以查看class_name的每个实例:“Follow”,其中User是追随者(即@user.followees
)通过:用户的:followee_follows。要确定用户:关注者(在foreign_key: :follower_id
调用数据库时),Rails现在可以查看class_name的每个实例:“关注”这样的用户是跟随者(即@user.followers
)至:例如用户:follower_follows。
答案 2 :(得分:6)
如果有人来到这里试图找出如何在Rails中创建朋友关系,那么我会将它们引用到我最终决定使用的内容,即复制“社区引擎”所做的事情。
您可以参考:
https://github.com/bborn/communityengine/blob/master/app/models/friendship.rb
和
https://github.com/bborn/communityengine/blob/master/app/models/user.rb
了解更多信息。
TL; DR
# user.rb
has_many :friendships, :foreign_key => "user_id", :dependent => :destroy
has_many :occurances_as_friend, :class_name => "Friendship", :foreign_key => "friend_id", :dependent => :destroy
...
# friendship.rb
belongs_to :user
belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
答案 3 :(得分:1)
对于双向belongs_to_and_has_many
,请参阅已发布的优秀答案,然后使用其他名称创建另一个关联,反转外键并确保将class_name
设置为指向正确的模型。欢呼声。
答案 4 :(得分:1)
受@StéphanKochen的启发, 这可能适用于双向关联
class Post < ActiveRecord::Base
has_and_belongs_to_many(:posts,
:join_table => "post_connections",
:foreign_key => "post_a_id",
:association_foreign_key => "post_b_id")
has_and_belongs_to_many(:reversed_posts,
:class_name => Post,
:join_table => "post_connections",
:foreign_key => "post_b_id",
:association_foreign_key => "post_a_id")
end
然后post.posts
&amp;&amp; post.reversed_posts
应该都有效,至少对我有用。
答案 5 :(得分:0)
如果有人在获得优秀工作答案方面遇到问题,例如:
(对象不支持#inspect)
=&GT;
或
NoMethodError:未定义方法`split'for:Mission:Symbol
然后解决方案是用:PostConnection
替换"PostConnection"
,当然替换你的类名。