我有一个名为Conversation
的模型,其中包含两个属性user_1 and user_2
和以下验证:
class Conversation < ActiveRecord::Base
2.times { |time| belongs_to :"user_#{time + 1}", class_name: 'User' }
has_many :messages, dependent: :destroy
validates :user_1, :user_2, presence: true
validates :user_1_id, uniqueness: { scope: :user_2_id,
message: 'Cannot have two conversation with the same user' }
validates :user_2_id, uniqueness: { scope: :user_1_id,
message: 'Cannot have two conversation with the same user' }
end
这些验证将避免:
user_1 | user_2 user_1 | user_2
1 | 2 and also 2 | 1
1 | 2 2 | 1
是否可以添加活动记录验证以避免这些?
user_1 | user_2
1 | 2
2 | 1
答案 0 :(得分:0)
没有内置验证器,但您可以使用自定义验证
def validate(conv)
unless Conversation.where(user_1_id: conv.user_2_id, user_2_id, conv.user_1_id).empty?
record.errors[:base] << "duplicate conversation exists"
end
end
注意 - 就像所有rails内部验证一样,这实际上并不能保证由于数据库访问的竞争条件而永远不会得到两个对话,因为你还需要在数据库中有一个匹配的唯一索引,对于这种类型的索引,它将依赖于数据库(如果它实际上可以用于您正在使用的数据库)
答案 1 :(得分:0)
您可以在对话模型中将范围验证定义为
scope :between, -> (user_1_id,user_2_id) do
where(“(conversations.user_1_id = ? AND conversations.user_2_id =?) OR (conversations.user_1_id = ? AND conversations.user_2_id =?)”, user_1_id,user_2_id, user_2_id, user_1_id)
end
并将其用作:
@conversation = Conversation.between(id1,id2)
来源:link