ruby-on-rails - 在连接表中查找具有相同链接的条目
问题描述
在我的聊天应用程序中,我有users
和chats
。每个表都通过连接表连接:
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_id
s 列表的聊天,但我无法找到一种理智的方法来做到这一点。如何才能做到这一点?
解决方案
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.
推荐阅读
- java - 如何检查方程式是否包含多位数字
- android - NotificationController not found 你需要调用 Get.put 或 Get.lazyPut
- symfony - 命令“生成类型”未定义
- mongodb - 使用连接在 mongo db 中进行复杂查询
- python - 使用python在内存中创建文件并为文件分配名称(通用命名约定)?
- javascript - 布尔玛扩展不再起作用
- c - 分段错误,转换到/从指针到/从不同大小的整数
- power-automate - 如何将撰写输出用于创建事件流?
- angular - 使用 ng-zorro 和 tabset 的角度高度动画
- apollo - 从本地存储竞争问题设置授权标头?