Rails验证相关模型

时间:2016-08-07 20:13:54

标签: ruby-on-rails validation

我试图阻止用户创建重复的聊天室(聊天室包括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作为聊天室表中的属性,因为我想添加连接聊天功能,以便根据需要添加任意数量的内容。

1 个答案:

答案 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中。