55

Rubyで次のDB移行を想定します。

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

      t。タイムスタンプ
    終わり

さらに、DB内の行に一意の(user_id、question_id)ペアが含まれていることを望みます。それを達成するためにモデルに入れるのに適切なほこりは何ですか?

validates_uniqueness_of:user_id、:question_id
行をペアで一意にするのではなく、ユーザーIDで一意にし、質問IDで一意にするようです。

4

6 に答える 6

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

別の列(またはそれ以上)を含める必要がある場合は、それをスコープに追加することもできます。例:

validates_uniqueness_of :user_id, :scope => [:question_id, :some_third_column]
于 2009-05-29T00:12:40.747 に答える
27

mysql を使用している場合は、一意のインデックスを使用してデータベースで実行できます。それは次のようなものです:

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

これは、question_id/user_id の 2 つの組み合わせを保存しようとすると例外が発生するため、実験して、どの例外をキャッチして処理するかを判断する必要があります。

于 2010-06-24T08:27:31.807 に答える
17

一意性の検証が行われた場合、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% 安全に確認できます :)

于 2015-02-06T12:01:14.037 に答える
15

RailsGuidesから。validatesも動作します:

class QuestionVote < ActiveRecord::Base
  validates :user_id, :uniqueness => { :scope => :question_id }
end
于 2012-08-16T07:13:09.590 に答える
10

独自の検証メソッドを作成することを除いて、あなたができる最善のことvalidates_uniqueness_ofはこれです:

validates_uniqueness_of :user_id, :scope => "question_id"

これにより、user_idが、挿入しようとしているレコードと同じquestion_idを持つすべての行内で一意であることが確認されます。

しかし、それはあなたが望むものではありません

私はあなたがデータベース全体でユニークであるという組み合わせ:user_idを探していると信じています。:question_id

その場合、2つのことを行う必要があります。

  1. 独自の検証メソッドを作成します。
  2. アプリが2つのレコードを同時に処理する可能性があるため、データベースに制約を作成します。
于 2009-05-29T00:14:09.480 に答える