Jeder Hacker, der mit
Ruby On Rails gearbeitet hat, ist mit
ORM ActiveRecord vertraut. Wir werden eine der vorgeschlagenen Validierungen sofort diskutieren, nämlich Validierungen auf Eindeutigkeit, und warum das Juwel
database_validations die Konsistenz Ihrer Datenbank spart.
Angenommen, Sie haben ein Benutzermodell mit Eindeutigkeit im
E-Mail- Feld, d. H.
class User < ApplicationRecord validates :email, uniqueness: true end
Möglicherweise wissen Sie bereits, dass diese Validierung die folgende Anforderung ausführt
SELECT 1 FROM users WHERE email = $1
Jedes Mal, wenn wir versuchen, einen Datensatz in der Datenbank zu speichern.
Dieser Ansatz hat mehrere Nachteile:
Erstens die Ausführung einer zusätzlichen Anforderung, und wenn im Modell mehrere Eindeutigkeitsüberprüfungen initialisiert werden, wird die Anforderung für jede von ihnen ausgeführt. Dies ist nicht effizient und erfordert auch Indizes, wenn diese Abfragen schnell ausgeführt werden sollen.
Zweitens garantiert diese Lösung aufgrund eines möglichen
Wettlaufs um Daten keine Eindeutigkeit. Mehrere Wettbewerbsvorgänge können gleichzeitig feststellen, dass kein bestimmter Datensatz vorhanden ist, wodurch dieselben Daten gespeichert werden.
Natürlich können seltene Fälle mit Datenrennen durch Hinzufügen einer Eindeutigkeitsbeschränkung auf Datenbankebene gelöst werden. In diesem Fall wird jedoch kein Validierungsfehler angezeigt. Die Abfrage an die Datenbank wird einfach gelöscht und die gesamte Transaktion wird zurückgesetzt.
In dieser Situation hilft gem
database_validations , wodurch die Kompatibilität zwischen Datenbankbeschränkungen und Validierungen gewährleistet wird.
Die Hauptbedeutung von Edelstein wird im folgenden Code dargestellt:
def save(options = {}) ActiveRecord::Base.connection.transaction(requires_new: true) { super } rescue ActiveRecord::RecordNotUnique => e Helpers.handle_unique_error!(self, e) false end
Daher versuchen wir, die Daten zu speichern. Wenn alle anderen Überprüfungen bestanden sind, wenn die Transaktion ausfällt und zurückgesetzt wird, analysieren wir den Fehler und weisen den
errors
unseres Objekts die richtigen Werte zu.
Nach Durchsicht der
Dokumentation und der
Benchmarks können wir den Schluss ziehen, dass dieses Juwel das Speichern von Datensätzen in der Datenbank mindestens zweimal beschleunigt.
Dank der Unterstützung von Datenbanken wie
PostgreSQL ,
SQLite ,
MySQL und der Abwärtskompatibilität mit
validates_db_uniqueness_of
dauert das Ersetzen durch
validates_db_uniqueness_of
nur wenige Minuten.
Ein praktischer Matcher für RSpec ist ebenfalls sofort verfügbar:
specify do expect(described_class) .to validate_db_uniqueness_of(:field) .with_message('duplicate') .with_where('(some_field IS NULL)') .scoped_to(:another_field) .with_index(:unique_index) end
Wenn Sie zu einer neuen Validierung wechseln, müssen Sie Einschränkungen hinsichtlich der Eindeutigkeit in der Datenbank haben. Wenn diese jedoch noch nicht vorhanden sind, zeigt gem dies beim Start der Anwendung an.
Der Edelstein wurde an einer Anwendung mit mehr als 100 Validierungen auf Einzigartigkeit unter mehr als 50 Modellen getestet.
Verwenden Sie Edelstein und teilen Sie Ihre Meinung. Jeder Beitrag zur Weiterentwicklung ist willkommen!