我试图阻止用户创建重复的聊天室(聊天室包括2个用户)。但我不知道如何在保存之前验证具有相同用户的聊天室是否已存在。
<小时/> 这是我在聊天室控制器中的创建方法:
def create
@chatroom = Chatroom.new
@friend = User.where(username: params[:friend]).last
@chatroom.chatroom_users.build(user: @friend, chatroom: @chatroom)
@chatroom.chatroom_users.build(user: current_user, chatroom: @chatroom)
if @chatroom.save
flash[:notice] = "chatrooom created"
redirect_to @chatroom
else
flash[:notice] = "chatrooom not created lol"
redirect_to authenticated_root_path
end
end
这就是我试图验证是否有2个用户的聊天室,例如新用户:
在我的班级聊天室
after_save :duplicate?
# Checks if chatroom containing specific users exists.
def duplicate?
user = self.users.first
friend = self.users.second
# lines below work fine - they check if there is already such chatroom
(Chatroom.all - [self]).each do |chatroom|
if ((chatroom.users & [user, friend]) - [user, friend]).empty?
self.errors.add(:chatroom, "Such chatroom already exists.")
end
end
end
问题是:如果我在验证方法中使用after_save
我可以让self.users.first设置用户和朋友变量,但是它不会停止创建记录,我不确定如果删除它有一个好主意。其次 - 我使用validate
而不是after_save
self.users.first和self.users.second返回nil,所以我无法检查重复项。
PS:我不希望将用户ID作为聊天室表中的属性,因为我想添加连接聊天功能,以便根据需要添加任意数量的内容。
答案 0 :(得分:2)
这样的事情怎么样?
def duplicate?
is_duplicate = (Chatroom.all.to_a - [self]).any? do |chatroom|
chatroom.users.map(&:id).sort == self.chatroom_users.map(&:user_id).sort
end
if is_duplicate
errors.add(:chatroom, "Such chatroom already exists.")
end
end
以下是所有型号。
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
class Chatroom < ApplicationRecord
has_many :chatroom_users, :dependent => :destroy
has_many :users, :through => :chatroom_users
before_validation :duplicate?
def duplicate?
is_duplicate = (Chatroom.all.to_a - [self]).any? do |chatroom|
chatroom.users.map(&:id).sort == self.chatroom_users.map(&:user_id).sort
end
if is_duplicate
errors.add(:chatroom, "Such chatroom already exists.")
end
end
end
class ChatroomUser < ApplicationRecord
belongs_to :chatroom
belongs_to :user
end
class User < ApplicationRecord
has_many :chatroom_users, :dependent => :destroy
has_many :chatrooms, :through => :chatroom_users
end
这是一个测试
require 'test_helper'
class ChatroomTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
test 'does not allow duplicate chatrooms' do
first_user = User.create!
second_user = User.create!
chatroom = Chatroom.create!
chatroom.chatroom_users.build(user: first_user, chatroom: chatroom)
chatroom.chatroom_users.build(user: second_user, chatroom: chatroom)
chatroom.save!
duplicate_chatroom = Chatroom.create!
duplicate_chatroom.chatroom_users.build(user: first_user, chatroom: chatroom)
duplicate_chatroom.chatroom_users.build(user: second_user, chatroom: chatroom)
assert !duplicate_chatroom.valid?
end
end
注意:此代码位于Rails 5中。