用户之间如何实现有很多直通关系

时间:2018-09-06 16:31:14

标签: ruby-on-rails ruby rails-activerecord

我正在建立用户之间的匹配系统,最初它是拥有并且属于许多关联,但是由于需要一些验证和其他数据,因此我需要该联接表,因此我需要为该联接表建立模型,并将其更改为has许多通过。

has_and_belongs_to_many(:likes,
    class_name: :User,
    join_table: :user_likes,
    foreign_key: :user_liker_id,
    association_foreign_key: :user_liked_id)

has_and_belongs_to_many(:likeds,
    class_name: :User,
    join_table: :user_likes,
    foreign_key: :user_liked_id,
    association_foreign_key: :user_liker_id)

这是旧的实现,需要通过将其转换为has_many来实现。如您所见,借助这一功能,我可以检索我喜欢的所有用户和喜欢我的用户。我已经创建了UserLike模型,但是在用户模型中使其可行并没有成功。我已经尝试过的是:

user.rb

has_many :user_likes
has_many :likes, through: :user_likes, foreign_key: :user_liked_id
has_many :likeds, through: :user_likes, foreign_key: :user_liker_id

user_like.rb

class UserLike < ApplicationRecord
    belongs_to :user
end

此实现引发以下异常:

  

ActiveRecord :: HasManyThroughSourceAssociationNotFoundError:在模型UserLike中找不到源关联“ like”或:likes。尝试'has_many:likes,:through =>:user_likes,:source =>'。是user还是user_likes之一?

我不知道我在这里想念的是什么,将不胜感激:)

2 个答案:

答案 0 :(得分:1)

在创建将同一张表连接两次的连接表时,您需要两个单独的关联,因为用户可以使用任一外键:

class User < ApplicationRecord
  has_many :likes_as_liker,
    class_name: 'Like',
    foreign_key: 'liker_id'
  has_many :likes_as_liked,
    class_name: 'Like',
    foreign_key: 'liked_id'
end

class Like < ApplicationRecord
  belongs_to :liker, class_name: 'User'
  belongs_to :liked, class_name: 'User'
end

完成两个has_many关联后,我们可以开始创建间接关联:

class User < ApplicationRecord
  has_many :likes_as_liker,
    class_name: 'Like',
    foreign_key: 'liker_id'
  has_many :likes_as_liked,
    class_name: 'Like',
    foreign_key: 'liked_id'
  has_many :likers,
    through: :likes_as_liked
  has_many :liked_users,
      through: :likes_as_liker,
      source: :liked
end

哪个效果很好:

irb(main):002:0> u.likers
  User Load (2.8ms)  SELECT  "users".* FROM "users" INNER JOIN "likes" ON "users"."id" = "likes"."liker_id" WHERE "likes"."liked_id" = $1 LIMIT $2  [["liked_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy []>
irb(main):003:0> u.liked_users
  User Load (1.3ms)  SELECT  "users".* FROM "users" INNER JOIN "likes" ON "users"."id" = "likes"."liked_id" WHERE "likes"."liker_id" = $1 LIMIT $2  [["liker_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy []>

答案 1 :(得分:0)

按照帖子中提到的描述,您要查找喜欢我帖子的用户和喜欢我的用户。

下面提到的代码不会告诉rails点赞和点赞实际上是用户。

has_many :user_likes
has_many :likes, through: :user_likes, foreign_key: :user_liked_id
has_many :likeds, through: :user_likes, foreign_key: :user_liker_id

修改为以下

has_many :user_likes
has_many :likes, through: :user_likes, foreign_key: :user_liked_id, source: :liked
has_many :likeds, through: :user_likes, foreign_key: :user_liker_id, source: :liked

最佳方法是指定类以及类名,以便在指定自定义关系名称时,rails知道将哪个类映射到此外键

当您的关联名称不同于:through所使用的名称时,您必须定义source参数。如果您查看异常消息,它将明确要求您执行操作。

希望它能回答问题。