【问题标题】:Rails: Validate Unique PairsRails:验证唯一对
【发布时间】:2018-04-30 09:27:56
【问题描述】:

我有一个名为“用户”的模型。我希望两个用户与我的对话模型相关联,但我希望用户对 (User1, User2) 是唯一的。例如,如果 user1 为 5,user2 为 6,则不能存在 user1 为 6 且 user2 为 5 的对。

我已经确定两个用户不相同/没有 User1 和 User2 组合相同

validates :user1_id, uniqueness: { scope: :user2_id}

但是如何确保如果与 User1 和 User2 进行对话,则不能与 User2 和 User1 进行对话?另外,我怎样才能确保 User1 和 User2 不一样? (即,如果 User1 为 6 且 User2 也为 6,则无效)

【问题讨论】:

  • @Gerry 我编辑了帖子,所以它不是重复的!

标签: ruby-on-rails ruby database model


【解决方案1】:

我建议custom validation method

validate :validate_users_are_unique

private

def validate_users_are_unique
  if self.class.where(user1_id: user1_id, user2_id: user2_id)
               .or(self.class.where(user1_id: user2_id, user2_id: user1_id))
               .exists?
    errors.add(:base, 'User 1 and User 2 combination exists!')
  end
end

另一个选项可能是对用户 ID 进行排序并确保 user1_id 始终是两者中较小的一个。然后可以使用默认的 Rails 的唯一性验证。并且可以通过添加唯一索引在数据库级别确保唯一性:

# in the model
before_validation :sort_user_ids
validates :user1_id, uniqueness: { scope: :user2_id }

private

def sort_user_ids
  self.user1_id, self.user2_id = [user1_id, user2_id].sort
end

# in a migration
add_index :table_name, [:user1_id, :user2_id], unique: true

【讨论】:

  • 请记住,验证实际上并不能保证数据库的完整性。您的 Rails 验证可能会通过,但您的数据库中仍可能出现无效条目。确保真正一致性的唯一方法是通过数据库级​​约束、外键和唯一索引。
  • @chickenburgers 这对于应用程序中的所有类型的唯一性验证器都是正确的。但我不确定是否可以为这种约束配置唯一索引。也许总是对用户 ID 进行排序可能是值得的(user1_id 总是较小的 ID,user2_id 总是较大的)。然后使用唯一数据库索引的默认 Rails 唯一验证将起作用。这是否可能取决于user1user2 的排序是否有意义。
  • @spickermann 您所说的“在验证中”,我认为您的意思是“在迁移中”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-03
  • 2020-05-18
  • 2016-03-29
  • 2011-11-17
相关资源
最近更新 更多