【问题标题】:How to achieve has many through relation between users如何实现用户之间的多通关系
【发布时间】:2019-02-11 23:36:42
【问题描述】:

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

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 模型,但我没有成功使它在用户模型中可用。我已经尝试过的是:

用户.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 之一?

我不知道我在这里缺少什么,任何帮助将不胜感激:)

【问题讨论】:

  • 尝试为两个关联指定class_name: 'User'

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


【解决方案1】:

根据帖子中提到的描述,您正在尝试找到喜欢我的帖子的用户和我喜欢的用户。

下面提到的代码并没有告诉 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 中使用的名称不同时,您必须定义源参数。如果您查看异常消息,它会明确要求您执行此操作。

希望它能回答问题。

【讨论】:

    【解决方案2】:

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

    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 []>
    

    【讨论】:

    • 我对命名有些随意,因为它比实际需要的要复杂。
    • 非常感谢,稍作改动,我就可以正常工作了。顺便说一句,你对这个实现有什么想法,我怎么能检索到匹配用户的数量和根本没有匹配的用户?
    • 这确实是一个单独问题的主题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多