Understanding Rails Custom Validations
Lassen Sie uns eine Anforderung betrachten und dann die Notwendigkeit von jedem, oder einem von ihnen verstehen:
Betrachten wir, dass wir ein Item-Modell mit dem Tabellennamen items
haben, wo jeder Datensatz ein Paket mit den Attributen title
, description
, width
, height
, depth
und weight.
Jedes Item muss den folgenden Regeln gehorchen:
- Wir möchten, dass der Titel mindestens 10 Zeichen lang ist und jeder Titel ein Schlüsselwort enthält, z. B.e.
great-article
. - Das Volumen des Artikels muss zwischen 20 und 3000 Kubikmetern liegen (d.h.. Volumenvalidierung)
- Die Kompaktheit des Gegenstands darf 200 Gramm pro Kubikmeter nicht überschreiten (d. h.
Compactness Validation
) - Keine Seitenlänge darf weniger als 15% der größten Seite betragen (d. h. Proportionsvalidierung).
Nun lassen Sie uns die erste Regel aufgreifen, mit dem ersten Ansatz
- Verwenden Sie eine benutzerdefinierte Methode, um die Validierung durchzuführen.
Wir haben den allerersten Ansatz für die benutzerdefinierte Validierung verwendet, d.h. eine validate-Methode innerhalb der Modellklasse definiert.
Das funktioniert gut, aber es fügt dem Modell auch mehr Logik hinzu. Es ist vorzuziehen, die Logik in eine separate Hilfsklasse zu extrahieren, wann immer dies möglich ist. Das liegt daran, dass die gesamte Logik für eine bestimmte Validierung in einem eigenen Objekt gekapselt ist, was die Fehlersuche erleichtert.
Lassen Sie uns die Dichte mit Hilfe des zweiten Ansatzes validieren, d.h. durch Erstellen einer Hilfsklasse validator. Die von Rails bereitgestellte #validates_with
Methode verweist die Validierung an eine Hilfsklasse:
class Item < ActiveRecord::Base
…
validates_with CompactnessValidator
…
end
Nun müssen wir eine Hilfsklasse erstellen CompactnessValidator
Erstelle im Verzeichnis /models/concerns die Datei „compactness_validator.rb“. Die CompactnessValidator
erbt von ActiveModel::Validator
, deren Eigenschaft es ist, eine Methode namens #validate
zu haben. Diese Methode kann auf den gesamten Datensatz zugreifen. Und kann bei Bedarf Fehler auf den Datensatz anwenden.
class CompactnessValidator << ActiveModel::Validator
def validate(record)
if record.compactness > 10
record.errors.add(:compactness, "is too high to safely dispatch")
end
end
end
Beachten Sie, dass wir in dieser Klasse n-Validierungen für verschiedene Attribute hinzufügen können. z.B. können wir sogar eine Validierung für den Titel in dieser Klasse hinzufügen.
z.B.
Nun lassen Sie uns den dritten Ansatz der Definition von benutzerdefinierten Validierungen verwenden.
Durch das Erstellen einer benutzerdefinierten Validierungshilfe können wir sie direkt verwenden, genau wie die von Rails eingebauten, indem wir einfach sagen: „item_dimensions_proportion:true“.
class Item < ActiveRecord::Base
...
validates :height, :width, :depth, item_dimensions_proportion: true
...
end
Nun, da wir das item_dimensions_proportion-Flag auf true gesetzt haben, erwartet Rails nun eine Hilfsklasse für die Validierung namens ItemDimensionsProportionValidator. Also im models concern Verzeichnis eine Datei „item_dimensions_proportion_validator.rb“ erstellen.
Wir müssen eine #validates_each
Methode definieren, um die Validierung zu erleichtern. Sie nimmt jedes Attribut und prüft den Wert entsprechend der Logik, die in der Methode validate_each geschrieben wurde.
Die Verwendung von benutzerdefinierten Validatoren ist eine großartige Sache, wenn man die Validierung im Zusammenhang mit dem Code in eine separate Klasse auslagern möchte. Es ist auch beim Debuggen sehr hilfreich, da der gesamte Validierungscode für ein Modell an einer Stelle liegt. Außerdem können wir sogar dieselben Validatoren für mehrere Klassen verwenden, was es wirklich praktisch und großartig macht.
Probieren Sie diese benutzerdefinierten Validatoren in Ihren Anwendungen aus, und lassen Sie mich wissen, ob Ihnen das geholfen hat. Sie können mich auch bei Problemen unter [email protected] erreichen.
Ich möchte auch meine Leserschaft vergrößern, also bitte ich Sie, diesen Blog mit Ihren Freunden, Kollegen usw. zu teilen, wenn Sie ihn hilfreich finden.
Danke.