validates_uniqueness_of :name, :case_sensitive => false
macht den Trick, aber Sie sollten bedenken, dass validates_uniqueness_of
dies keine Eindeutigkeit garantiert, wenn Sie mehrere Server / Serverprozesse (z. B. Phusion Passenger, mehrere Mongrels usw.) oder einen Multithread-Server haben. Das liegt daran, dass Sie möglicherweise diese Abfolge von Ereignissen erhalten (die Reihenfolge ist wichtig):
- Prozess A erhält die Anforderung, einen neuen Benutzer mit dem Namen 'foo' zu erstellen.
- Prozess B macht dasselbe
- Prozess A überprüft die Eindeutigkeit von 'foo', indem er die Datenbank fragt, ob dieser Name noch vorhanden ist, und die Datenbank sagt, dass der Name noch nicht vorhanden ist.
- Prozess B macht das Gleiche und erhält die gleiche Antwort
- Prozess A sendet die
insert
Anweisung für den neuen Datensatz und ist erfolgreich
- Wenn Sie eine Datenbankeinschränkung haben, die eine Eindeutigkeit für dieses Feld erfordert, sendet Prozess B die
insert
Anweisung für den neuen Datensatz und schlägt mit einer hässlichen Serverausnahme fehl , die vom SQL-Adapter zurückkommt. Wenn Sie keine Datenbankeinschränkung haben, ist die Einfügung erfolgreich und Sie haben jetzt zwei Zeilen mit dem Namen 'foo'.
Siehe auch "Parallelität und Integrität" in der validates_uniqueness_of
Rails-Dokumentation.
Von Ruby on Rails 3. Auflage :
... trotz seines Namens garantiert validates_uniqueness_of nicht wirklich, dass Spaltenwerte eindeutig sind. Sie können lediglich überprüfen, ob keine Spalte den gleichen Wert hat wie der Datensatz, der zum Zeitpunkt der Validierung validiert wird. Es ist möglich, dass zwei Datensätze gleichzeitig erstellt werden, jeder mit demselben Wert für eine Spalte, die eindeutig sein soll, und dass beide Datensätze die Validierung bestehen. Der zuverlässigste Weg, um die Eindeutigkeit durchzusetzen, ist eine Einschränkung auf Datenbankebene. "
Siehe auch die Erfahrung dieses Programmierers mit validates_uniqueness_of
.
Eine Möglichkeit, wie dies häufig vorkommt, sind versehentliche doppelte Übermittlungen von einer Webseite beim Erstellen eines neuen Kontos. Dies ist schwer zu lösen, da der Benutzer den zweiten (hässlichen) Fehler zurückerhält und denkt, dass die Registrierung fehlgeschlagen ist, obwohl dies in Wirklichkeit erfolgreich war. Der beste Weg, dies zu verhindern, besteht darin, Javascript zu verwenden, um eine doppelte Übermittlung zu verhindern.