モデルは次のとおりです(私はSQLLite3を使用しています)。
class School < ActiveRecord::Base
validates_uniqueness_of :name
end
たとえば、「エール」を追加した後、「エール」は追加できませんが、canは「エール」を追加します。検証で大文字と小文字を区別しないようにするにはどうすればよいですか?
編集:それを見つけました- アクティブレコード検証
validates_uniqueness_of :name, :case_sensitive => false
はトリックを行いますが、validates_uniqueness_of
はnotが複数のサーバー/サーバーを持っている場合に一意性を保証することに注意してくださいプロセス(Phusion Passenger、複数のMongrelsなどの実行)またはマルチスレッドサーバー。これは、次の一連のイベントを取得する可能性があるためです(順序は重要です)。
insert
ステートメントを送信し、成功しますinsert
ステートメントとfailを送信しますSQLアダプタから返されるいサーバー例外。データベース制約がない場合、挿入は成功し、「foo」という名前の2つの行ができます。validates_uniqueness_of
Railsドキュメント。
から Ruby on Rails 3rd Edition :
...その名前にもかかわらず、validates_uniqueness_ofは列の値が一意であることを実際に保証しません。検証の実行時に検証されるレコードの値と同じ値を持つ列がないことを確認するだけです。 2つのレコードが同時に作成され、それぞれが一意である必要がある列の値が同じであり、両方のレコードが検証に合格する可能性があります。一意性を強制する最も信頼できる方法は、データベースレベルの制約を使用することです。」
このプログラマーの経験 with validates_uniqueness_of
も参照してください。
これがよく発生する1つの方法は、新しいアカウントを作成するときにWebページから誤って二重送信されることです。ユーザーが返すのは2番目の(ugい)エラーであり、実際には成功したものの、登録が失敗したと思わせるため、これは解決が難しいものです。これを防ぐために私が見つけた最良の方法は、JavaScriptを使用して二重送信を防ぐことです。
大文字と小文字の区別を指定できるオプションがあります
validates_uniqueness_of :name, :case_sensitive => false
同様の質問がありますが、答えはもっと興味深いです。 https://stackoverflow.com/a/6422771
基本的に、:case_sensitive => false
は非常に非効率的なデータベースクエリを実行します。