我有一个名为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
您可以将Conversation模型中的范围验证定义为
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)
来源:链接
没有内置的验证器,但您可以使用自定义验证
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内部验证一样,由于数据库访问的竞争条件,这实际上并不能保证您永远不会进行两次对话,为此,您还需要在数据库中有一个匹配的唯一索引,该索引将依赖于这种类型的索引的数据库(如果您正在使用的数据库确实可以这样做的话)