可能な限り、データベースレベルとモデルレベルで検証してください。
なんで?手始めに、アクティブレコードはすべてのコンテキストで検証を強制するわけではありません。次のメソッドは検証をスキップし、有効性に関係なくオブジェクトをデータベースに保存します。
decrement!
decrement_counter
increment!
increment_counter
toggle!
touch
update_all
update_attribute
update_column
update_counters
に渡す:validate => false
とsave
、検証もスキップされます。詳細については、「検証のスキップ」に関する「アクティブレコードの検証とコールバックガイド」セクションを参照してください。(これが気になる場合は、これらのメソッドを無効にするための宝石もあります。)
したがって、理由1は、Railsの検証が決して完全に証明されていないことです。特に、一意性などのミッションクリティカルな検証では、Railsの検証だけに依存することは危険です。
そういえば、理由#2(頭のてっぺんから):activerecordの検証は競合状態になりがちであり、特にRailsの一意性バリデーターは一意性を保証できません。これがなぜそうなのかを文書化した多くの記事の1つです。
まれにしか発生しない場合がありますが、一意性制約に違反すると、データセット全体が破損する可能性があります。Railsがこれを実行しようとしているまれなケースでは、DBの一意性の制約が発生する場所で、すべてのコストでそれを停止する必要があります。データベースはこの状況を処理するように構築され、Railsが実行しない場合でも一貫して一意性を適用します。
そして理由#3:モデルとDBの両方で検証してみませんか?確かに、あなたは少し重複していますが、Railsが一意性検証チェックのようなものを見逃した場合の見返りと比較して、それは一般的にかなり小さな懸念です。これは実際にはどちらかまたは両方の提案ではありません。特に一意性などのミッションクリティカルな制約の場合は、可能な限りDBで検証を複製することをお勧めします。
とにかく、それらは私の考えです、それが役立つことを願っています。
参照:正確性が強制される場所(Gary Bernhardtによるスクリーンキャスト、表示するにはサブスクリプションが必要)