Ruby on Rails has_many 通过自我引用的跟随/跟随关系 [英] Ruby on Rails has_many through self-referential following/follower relationships
问题描述
has_many :through 上有许多帖子和主题,但我还没有找到任何专门涵盖我正在尝试做的事情的帖子和主题.
There are a number of posts and threads on has_many :through, but I haven't found any that cover specifically what I'm trying to do.
我有一个 User 模型和一个 Friendships 模型.一个用户有很多关注他们的用户,也有很多关注者.这是通常的 Twitter 模型.
I have a User model and a Friendships model. A user has many users that are following them, as well as many followers. It is the usual Twitter model.
对于给定的用户,我想设置 Active Record 关系,以返回关注该用户以及该用户是其关注者的实际用户.
For a given user, I want to setup Active Record relationships that return the actual users that are following the user and that the user is a follower of.
这些是我建立的关系:
class User < ActiveRecord::Base
has_many :following, :class_name => 'User', :through => :friendships, :foreign_key => 'user_id'
has_many :followers, :class_name => 'User', :through => :friendships, :foreign_key => 'friend_id'
end
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :following, :class_name => 'User', :foreign_key => 'friend_id'
belongs_to :follower, :class_name => 'User', :foreign_key => 'user_id'
end
以下关系有效 - 它生成以下连接:
The Following relationship works - it generates the below join:
SELECT `users`.* FROM `users` INNER JOIN `friendships` ON `users`.id = `friendships`.friend_id WHERE ((`friendships`.user_id = 1))
一切都很美好.
但是,Follower 关系不起作用.我尝试了许多变体,但大多数似乎返回与以下相同的结果集.
However, the Follower relationship does not work. I've tried a number of variations, but most seem to return the same set of results as Following.
我需要按如下方式设置连接以返回正确的结果集.
I need the join to be setup as follows to return the correct result set.
SELECT `users`.* FROM `users` INNER JOIN `friendships` ON `users`.id = `friendships`.user_id WHERE ((`friendships`.friend_id = 1));
我哪里出错了?
我可以使用 has_many 上的 finder_sql 选项进行设置,但似乎应该有更好的方法.
I can set this up using the finder_sql option on the has_many, but it seems like there should be a better way.
has_many :followers, :class_name => 'User', :finder_sql => 'SELECT `users`.* FROM `users` INNER JOIN `friendships` ON `users`.id = `friendships`.user_id WHERE ((`friendships`.friend_id = #{ id }))'
谢谢!
我取得了一些进展,最终通过将关系分成两部分来建立关系,如以下回复所示:自引用 has_many :through 自定义:primary key issue
I made a bit of progress and finally got the relationship working by breaking the relationships into two parts, as was shown in this response: Self-referential has_many :through with customized :primary key issue
# FOLLOWING
has_many :friendships_to, :foreign_key => 'user_id', :class_name => 'Friendship'
has_many :following, :through => :friendships_to, :class_name => 'User'
# FOLLOWERS
has_many :friendships_from, :foreign_key => 'friend_id', :class_name => 'Friendship'
has_many :followers, :through => :friendships_from, :class_name => 'User'
然而,虽然可以有一个单行版本的关系用于后续
However, while it was possible to have a one-line version of the relationship for following
has_many :following, :class_name => 'User', :through => :friendships, :foreign_key => 'user_id'
我仍然无法让它为追随者工作.仍然想知道如何做到这一点?
I still wasn't able to get it to work for followers. Still wondering how this could be done?
推荐答案
您需要确保 ActiveRecord 知道 User#friends 和关注者的源关联,并为 ActiveRecord 可以的关系指定 class 和 foreign_key't 从关联名称推断.
You need to make sure ActiveRecord knows what the source association for the User#friends and likewise the followers and specify the class and foreign_key for the relationships that ActiveRecord can't extrapolate from the association names.
class Following < ActiveRecord::Base
belongs_to :user
belongs_to :followed, :class_name => 'User'
end
class User < ActiveRecord::Base
has_many :followings
has_many :friends, :through => :followings, :source => 'followed'
has_many :followeds, :class_name => 'Following', :foreign_key => 'followed_id'
has_many :followers, :through => :followeds, :source => :user
end
这篇关于Ruby on Rails has_many 通过自我引用的跟随/跟随关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!