首页 > 解决方案 > 在连接表中查找具有相同链接的条目

问题描述

在我的聊天应用程序中,我有userschats。每个表都通过连接表连接:

class User < ApplicationRecord 
  has_and_belongs_to_many :chats_users
  has_and_belongs_to_many :chats, :through => :chats_users
end

class Chat < ApplicationRecord
  has_and_belongs_to_many :chats_users
  has_and_belongs_to_many :users, :through => :chats_users
end

class ChatsUsers < ApplicationRecord
    belongs_to :chat, class_name: 'Chat'
    belongs_to :user, class_name: 'User'
    validates :ad_id, presence: true
    validates :tag_id, presence: true
end

和中的倒数chat.rb

在使用 s 的参与列表创建新聊天时user_id,我想首先检查是否存在具有完全相同的关联user_ids 列表的聊天,但我无法找到一种理智的方法来做到这一点。如何才能做到这一点?

标签: ruby-on-railspostgresqljoin

解决方案


has_and_belongs_to_many仅在您不需要连接模型(或您最初认为不需要它)作为其无头模型的情况下使用。相反,您想使用has_many through:

class User < ApplicationRecord 
  has_many :chat_users
  has_many :chats, through: :chat_users
end

class Chat < ApplicationRecord
  has_many :chat_users
  has_many :users, through: :chat_users
end

class ChatUser < ApplicationRecord
   belongs_to :chat
   belongs_to :user
   # not needed if these are belongs_to associations in Rails 5+
   validates :ad_id, presence: true
   validates :tag_id, presence: true
end

您可能需要创建迁移以将表的名称更改为chat_users并确保它具有主键。

has_and_belongs_to_many uses an oddball plural_plural naming scheme that will cause rails to infer that the class is named Chats::User since plural words are treated as modules. While you can work around that by explicitly listing the class name its better to just align your schema with the conventions.

If your still just messing about in development roll back and delete the migration that created the join table and run rails g model ChatUser chat:belongs_to user:belongs_to to generate the correct table with a primary key and timestamps.

If you want to select chats connected to a given set of users:

users = [1,2,3]
Chat.joins(:users)
    .where(users: { id: users })
    .group(:id)
    .having(User.arel_table[Arel.star].count.eq(users.length))
    .exists?

Note that you don't really need to tell ActiveRecord which table its going through. Thats the beauty of indirect associations.


推荐阅读