15

重複の可能性:
Ruby on Rails:モデルまたはデータベースで検証する方が良いですか?

Railsモデルと移行の両方で同じ制約/検証を追加できることがわかりました。しかし、どちらが最善のアプローチですか?モデルレベルとデータベースレベルの両方で検証することは良い習慣ですか(そしてその理由)?またはそれらはレールでも同じですか?

たとえば、モデルと移行の両方で名前に対して同じ検証を行うことができます

class User < ActiveRecord::Base
  validates :name, :uniqueness => true, :presence => true
end

class CreateUser < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name, :unique => true, :null => false
    end
  end
end
4

1 に答える 1

29

可能な限り、データベースレベルとモデルレベルで検証してください。

なんで?手始めに、アクティブレコードはすべてのコンテキストで検証を強制するわけではありません。次のメソッドは検証をスキップし、有効性に関係なくオブジェクトをデータベースに保存します。

decrement!
decrement_counter
increment!
increment_counter
toggle!
touch
update_all
update_attribute
update_column
update_counters

に渡す:validate => falsesave、検証もスキップされます。詳細については、「検証のスキップ」に関する「アクティブレコードの検証とコールバックガイド」セクションを参照してください。(これが気になる場合は、これらのメソッドを無効にするための宝石もあります。)

したがって、理由1は、Railsの検証が決して完全に証明されていないことです。特に、一意性などのミッションクリティカルな検証では、Railsの検証だけに依存することは危険です。

そういえば、理由#2(頭のてっぺんから):activerecordの検証は競合状態になりがちであり、特にRailsの一意性バリデーターは一意性を保証できません。これがなぜそうなのかを文書化した多くの記事の1つです。

まれにしか発生しない場合がありますが、一意性制約に違反すると、データセット全体が破損する可能性があります。Railsがこれを実行しようとしているまれなケースでは、DBの一意性の制約が発生する場所で、すべてのコストでそれを停止する必要があります。データベースはこの状況を処理するように構築され、Railsが実行しない場合でも一貫して一意性を適用します。

そして理由#3:モデルとDBの両方で検証してみませんか?確かに、あなたは少し重複していますが、Railsが一意性検証チェックのようなものを見逃した場合の見返りと比較して、それは一般的にかなり小さな懸念です。これは実際にはどちらかまたは両方の提案ではありません。特に一意性などのミッションクリティカルな制約の場合は、可能な限りDBで検証を複製することをお勧めします

とにかく、それらは私の考えです、それが役立つことを願っています。

参照:正確性が強制される場所(Gary Bernhardtによるスクリーンキャスト、表示するにはサブスクリプションが必要)

于 2012-10-29T14:13:54.613 に答える