アクティブレコードのvalidates_uniqueness_of
はvulnerable to race conditionsです。本当に一意性を保証するには、追加のセーフガードが必要です。 ActiveRecordのRDocsから1つの提案は、あなたの移行に含めることによって、例えば、データベース上の一意のインデックスを作成することです:ActiveRecordオブジェクトが一意のデータベースのキー/インデックスに違反しているかどうかを確認するにはどうすればよいですか?
add_index :recipes, :name, :unique => true
これは、名前が一意であることをデータベース・レベルで保証されます。しかし、このアプローチの欠点は、重複を保存しようとしたときに返される例外がそれほど役に立ちませんということです。エラーが複製されたレコードによって生成されただけでなく、壊れたSQLによって生成されたというこの例外をキャッチするときには、必ずしも確実ではありません。
RDocsが示唆しているように、1つの解決策は例外に付属するメッセージを解析し、「重複」または「一意」のような単語を検出しようとしますが、これはkludgyであり、メッセージはデータベースバックエンド固有です。 SqlLite3の場合、私の理解は、メッセージは完全に汎用的であり、このように解析することはできません。
これはActiveRecordユーザーにとって根本的な問題であることを考えると、これらの例外を処理するための標準的なアプローチがあるかどうかを知ることは良いことです。私は下に私の提案を提供します。コメントしてください。ありがとう!
私はこれを実装し、仕事を終えたようです。これは本質的に同じことをより効率的に行うので、validates_uniquenessを取り出すことを強いられました。関連するアップデートを投稿します。 – Chinasaur
非常に小さなニック・ピック:例外を取得して複製を照会するまでの間に複製が削除されると間違ったエラーが発生します。 – mpartel