繁体   English   中英

如何在Ruby on Rails中验证一对id的唯一性?

[英]How do you validate uniqueness of a pair of ids in Ruby on Rails?

假设在Ruby中进行以下数据库迁移:

create_table :question_votes do |t|
      t.integer :user_id
      t.integer :question_id
      t.integer :vote

      t.timestamps
    end

进一步假设我希望DB中的行包含唯一(user_id,question_id)对。 为了实现这一目标,在模型中投入的正确粉尘是什么?

validates_uniqueness_of :user_id, :question_id
似乎只是通过用户ID使行唯一,并且通过问题ID使其唯一,而不是由对唯一。

validates_uniqueness_of :user_id, :scope => [:question_id]

如果您需要包含另一列(或更多),也可以将其添加到范围。 例:

validates_uniqueness_of :user_id, :scope => [:question_id, :some_third_column]

如果使用mysql,则可以使用唯一索引在数据库中执行此操作。 它是这样的:

add_index :question_votes, [:question_id, :user_id], :unique => true

当您尝试保存question_id / user_id的双重组合时,这会引发异常,因此您必须尝试并找出要捕获和处理的异常。

来自RailsGuides validates也有效:

class QuestionVote < ActiveRecord::Base
  validates :user_id, :uniqueness => { :scope => :question_id }
end

最好的方法是使用两者,因为当唯一性验证通过时,rails不是100%可靠。

您可以使用:

  validates :user_id, uniqueness: { scope: :question_id }

并且在安全方面100%,在您的数据库上添加此验证(MySQL ex)

  add_index :question_votes, [:user_id, :question_id], unique: true

然后你可以使用以下方法处理你的控制器:

  rescue ActiveRecord::RecordNotUnique

所以现在你100%安全,你没有重复的价值:)

除了编写自己的验证方法之外,使用validates_uniqueness_of可以做的最好的是:

validates_uniqueness_of :user_id, :scope => "question_id"

这将检查user_id在所有行中是唯一的,其中的question_id与您尝试插入的记录相同。

但那不是你想要的

我相信你正在寻找:user_id:question_id的组合在整个数据库中是唯一的。

在这种情况下,您需要做两件事:

  1. 编写自己的验证方法。
  2. 在数据库中创建约束,因为您的应用程序仍有可能同时处理两个记录。

当您创建新记录时,这不起作用,因为您的父模型的id在验证时仍然不存在。

这应该适合你。

class B < ActiveRecord::Base
  has_many :ab
  has_many :a, :through => :ab
end

class AB < ActiveRecord::Base
  belongs_to :b
  belongs_to :a
end

class A < ActiveRecord::Base
  has_many :ab
  has_many :b, :through => :ab

  after_validation :validate_uniqueness_b

  private
  def validate_uniqueness_b
    b_ids = ab.map(&:b_id)
    unless b_ids.uniq.length.eql? b_ids.length
      errors.add(:db, message: "no repeat b's")
    end
  end
end

在上面的代码中,我得到参数集合的所有b_id ,然后比较唯一值和获得的b_id之间的长度是否等于。
如果等于表示没有重复b_id

注意:不要忘记在数据库的列中添加unique

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM