実際のレコードが単なる列ではなく、一意であることを検証するための方法はありますか?あなたはスコープvalidates_uniqueness_of
呼び出しは次のようにすることができます複数の列の一意性を確認する
user_id: 10 | friend_id: 20
user_id: 10 | friend_id: 20
実際のレコードが単なる列ではなく、一意であることを検証するための方法はありますか?あなたはスコープvalidates_uniqueness_of
呼び出しは次のようにすることができます複数の列の一意性を確認する
user_id: 10 | friend_id: 20
user_id: 10 | friend_id: 20
:たとえば、友情モデル/テーブルは以下のように複数の同一のレコードを持ってすることはできないはず。
validates_uniqueness_of :user_id, :scope => :friend_id
ちょうど複数のスコープパラメータを渡すことができます3つ以上のフィールドで一意性を検証する必要があります。私。 :scope => [:friend_id、:group_id] –
あなたは 'validates_uniqueness_of [:user_id、:friend_id]'と言うことはできません。おそらく、これにパッチを当てる必要がありますか? – Alexey
Alexey、validates_uniqueness_of [:user_id、:friend_id]はリストされた各フィールドの検証を行うだけで、文書化された動作が期待されます –
有効性が競合条件に苦しんでいるため、おそらくdbに実際の制約が必要です。
validates_uniqueness_of :user_id, :scope => :friend_id
あなたはユーザーインスタンスを保持
は、Railsは任意のユーザレコードが既に提供のuser_idで存在するかどうかを確認するためにSELECTクエリを実行して、モデルを検証します。レコードが有効であると判断された場合、RailsはINSERT文を実行してユーザを永続させます。これは、単一のプロセス/スレッドWebサーバーの単一のインスタンスを実行している場合に効果的です。2つのプロセス/スレッドが同じuser_idを持つユーザーを同じ時刻に作成しようとしている場合は、次のような状況が発生する可能性があります。
dbの固有のインデックスを使用すると、上記のような状況が発生します。このブログ記事から取ら
回答 - http://robots.thoughtbot.com/the-perils-of-uniqueness-validations
そして、Railsの移行システムを使用して、DB側の制約(複数の列間での固有の制約)をどのように達成できますか? –
http://stackoverflow.com/questions/4123610/how-to-implement-a-unique-index-on-two-columns-in-rails –
@LeeHanKyeolのようにすることができます def change add_index :users、:email、unique:true end end –
あなたは1列にuniqueness
を検証するためにvalidates
を使用することができます。
validates :user_id, uniqueness: {scope: :friend_id}
複数の列の検証のための構文は似ていますが、あなたがすべき代わりにフィールドの配列を指定します。
validates :attr, uniqueness: {scope: [:attr1, ... , :attrn]}
ただし、の場合、上記の検証アプローチは競合状態にあり、一貫性を保証することはできません。次の例を考えてみましょう:
データベーステーブルのレコードはN分野でユニークなことになっています。テーブル内の同じレコードを挿入するために別々のプロセスごと(アプリケーションサーバ、バックグラウンドワーカーサーバーまたはあなたがを使用しているものは何でも)、Accessデータベースで扱う
複数(2以上)同時要求、。
各プロセスは、同一のレコードがあるかどうかを検証します。nフィールド。
各リクエストの検証は正常に行われ、各プロセスは同じデータを持つテーブルにレコードを作成します。このような動作を回避するために
、1は、DBテーブルにユニーク制約を追加する必要があります。
class AddUniqueConstraints < ActiveRecord::Migration
def change
add_index :table_name, [:field1, ... , :fieldn], unique: true
end
end
警告:あなたは、次の移行を実行することにより、1つ(または複数)のフィールド(複数可)のためadd_index
ヘルパーでそれを設定することができますが、ユニーク制約を設定した後でも、二つ以上の同時要求はなりますDBへ同じデータを書き込むために、代わりに重複するレコードを作成する、これはあなたが個別に処理する必要がありActiveRecord::RecordNotUnique
例外を発生させます試してみてください。
begin
# writing to database
rescue ActiveRecord::RecordNotUnique => e
# handling the case when record already exists
end
ありがとうございます! – nuc
DB制約:
add_index :friendships, [:user_id, :friend_id], unique: true
もし私が密集しているなら、私に許してください。しかし、この状況でどうすれば助けになるのですか? – re5et
あなたのモデルで "validates_uniqueness_of"を試してみてください。これは、 add_index:table、[:column_a、:column_b]、:unique => trueのような文を含むフィールドのマイグレーションを作成できるインデックスを作成しようとするとうまくいきません。 –
@HarryJoy、レールの道がありますか?そして、あなたは彼にノンレールの方法を提供しますが、標準です。 – Green