Rails:has_many通过表格为追随者,以下

时间:2016-06-29 18:02:18

标签: ruby-on-rails activerecord

我有一个用户模型,用户有很多关注者和关注者:通过连接:

has_many :connections
has_many :followers, :through => :connections, :foreign_key => :follower_id, :source => :user, class_name: User
has_many :following, :through => :connections, :foreign_key => :user_id, :source => :user, class_name: User

我的连接表有一个user_id(正在关注用户)和一个follower_id(正在关注的用户)。

我可以创建一个新连接:

Connection.create(user_id: 1, follower_id: 500)

我看到连接已创建,但我无法从相应的用户访问:

u = User.find(1)
u.followers => []
u.following => []

u = User.find(500)
u.followers => []
u.following => []

我哪里错了?

2 个答案:

答案 0 :(得分:0)

在第一个关系中,您拥有源:user,而您应该将其设为:follower

稍后编辑:

以上修复了一个问题,但完整的解决方案需要两个连接:一个用于follwers,另一个用于跟随:

class User < ActiveRecord::Base
  has_many :followers_connections, foreign_key: :user_id, class_name: "Connection"
  has_many :following_connections, foreign_key: :follower_id, class_name: "Connection"
  has_many :followers, through: :followers_connections, class_name: "User", source: :follower
  has_many :following, through: :following_connections, class_name: "User", source: :user
end


class Connection < ActiveRecord::Base
  belongs_to :user
  belongs_to :follower, class_name: "User"
end


# create some sample data
5.times { User.create }
Connection.create user_id: 1, follower_id: 2
Connection.create user_id: 1, follower_id: 3
Connection.create user_id: 4, follower_id: 1
Connection.create user_id: 5, follower_id: 1

# get followers
User.find(1).followers.pluck(:id) => [2, 3]
# SQL run: SELECT "users"."id" FROM "users" INNER JOIN "connections" ON "users"."id" = "connections"."follower_id" WHERE "connections"."user_id" = ?  [["user_id", 1]]

# get following
User.find(1).following.pluck(:id) => [4, 5]
# SQL run: SELECT "users"."id" FROM "users" INNER JOIN "connections" ON "users"."id" = "connections"."user_id" WHERE "connections"."follower_id" = ?  [["follower_id", 1]]

答案 1 :(得分:0)

更新关联如下,它们应该适合您。

has_many :connections
has_many :followers, through: :connections, class: 'User'
has_many :following, through: :connections, foreign_key: :follower_id, source: :user

<强>解释
1)当您说用户通过连接有很多关注者时, Rails 期望user_id表中的connections。在我们的案例中,我们在user_id表格中有connections Rails 期望连接中follower_id。在我们的例子中,我们在连接中有follower_id。但是从follower_id Rails推断follower作为模型,我们没有任何模型名称follower。因此,我们需要提及class: 'User'以用于检索followers

2)当您说用户has_many通过连接时,
Rails 期望user_id表中的connections。在我们的情况下,我们在连接中有user_id但我们不想使用此user_id来检索following,我们需要follower_id来检索following,所以我们需要提到foreign_key: :follower_id,以便Rails使用follower_id作为外键 Rails 期望following_id表中的connections。在我们的例子中,following_id表中没有connections。所以我们需要提一下source: :user,现在来自这个期望User模型的Rails是有效的。

来源:http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many