理解するために、私はコードに深く入りました。 仕様が失敗する理由は、データベース内のインデックスの一意性の違反の誤った処理です。 停止します。仕様とこの状況をチェックするためです。 エラー処理ブロックに移動します。はい、 ActiveRecord :: RecordNotUnique例外がキャッチされ、正しく処理されます。一意のインデックスを持つテーブルに一意でない値を挿入しようとするとActiveRecordがスローします。 この例外の生成がPostgreSQLのActiveRecordでどのように実装されるかを見ていきます。
ご覧のとおり、この例外またはその例外の生成は、データベースから返されたエラーメッセージに応じて発生します。 そして、すべてが適切に配置されます:PostgreSQLの設定(ファイル/etc/postgresql/8.4/main/postgresql.conf)で、このオプションが設定されます:
lc_messages = 'ru_RU.UTF-8' # locale for system error message
そして、予想される「重複するキー値が一意の制約に違反する」の代わりに、データベースはローカライズされた「重複するキー値が一意性条件に違反する」を返します。
だから誰が責任を負い、何をすべきか? 私の場合、PosgreSQL構成のエラーメッセージのローカライズを変更するだけで十分です。 しかし、一般的に、Railsコードでは、モデルに一意性検証を追加し(validate:field ,: uniqueness => true)、データベース例外のタイプに基づいてアプリケーションロジックを定式化しないことが最善です。
UPD。 この問題はPosgtreSQLアダプターにのみ関係します; MySQLでは、処理はテキストの説明ではなくエラーコードに基づいています。