Gibt es eine Möglichkeit, zu überprüfen, ob ein tatsächlicher Datensatz eindeutig ist und nicht nur eine Spalte? Beispielsweise sollte ein Freundschaftsmodell / eine Freundschafts-Tabelle nicht mehrere identische Datensätze enthalten können, wie z.
user_id: 10 | friend_id: 20
user_id: 10 | friend_id: 20
Is there a rails-way way
. Und Sie bieten ihm Weg ohne Schienen, aber Standard.The Active Record way claims that intelligence belongs in your models, not in the database.
validates :field_name, unique: true
ist es anfällig für Rennbedingungen, so dass eine tatsächliche Einschränkung bevorzugt wird, obwohl dies gegen den Schienenweg erfolgt. @ HarryJoy Ich werde eine Antwort, die den Weg der Einschränkung beschreibt, positiv bewerten.Antworten:
Sie können einen
validates_uniqueness_of
Anruf wie folgt ausführen.quelle
validates_uniqueness_of [:user_id, :friend_id]
. Vielleicht muss dies gepatcht werden?Sie können eine Spalte
validates
validierenuniqueness
:Die Syntax für die Validierung mehrerer Spalten ist ähnlich, Sie sollten jedoch stattdessen ein Array von Feldern angeben:
Die oben gezeigten Validierungsansätze haben jedoch eine Rennbedingung und können keine Konsistenz gewährleisten. Betrachten Sie das folgende Beispiel:
Datenbanktabellendatensätze sollen durch n Felder eindeutig sein ;
Mehrere ( zwei oder mehr ) gleichzeitige Anforderungen, die jeweils von separaten Prozessen verarbeitet werden ( Anwendungsserver, Hintergrundarbeitsserver oder was auch immer Sie verwenden ), greifen auf die Datenbank zu, um denselben Datensatz in die Tabelle einzufügen.
Jeder parallele Prozess überprüft, ob ein Datensatz mit denselben n Feldern vorhanden ist.
Die Validierung für jede Anforderung wird erfolgreich bestanden, und jeder Prozess erstellt einen Datensatz in der Tabelle mit denselben Daten.
Um diese Art von Verhalten zu vermeiden, sollte der Datenbank-Tabelle eine eindeutige Einschränkung hinzugefügt werden . Sie können es mit dem
add_index
Helfer für ein (oder mehrere) Felder festlegen, indem Sie die folgende Migration ausführen:Vorsichtsmaßnahme : Selbst nachdem Sie eine eindeutige Einschränkung festgelegt haben, versuchen zwei oder mehr gleichzeitige Anforderungen, dieselben Daten in db zu schreiben. Anstatt jedoch doppelte Datensätze zu erstellen, wird eine
ActiveRecord::RecordNotUnique
Ausnahme ausgelöst, die Sie separat behandeln sollten:quelle
Dies kann mit einer Datenbankeinschränkung für die beiden Spalten erfolgen:
add_index :friendships, [:user_id, :friend_id], unique: true
Sie könnten einen Rails-Validator verwenden, aber im Allgemeinen empfehle ich die Verwendung einer Datenbankeinschränkung.
Weitere Informationen: https://robots.thoughtbot.com/validation-database-constraint-or-both
quelle