Dies scheint wie es eine einfache Antwort haben sollte, aber nach viel Zeit auf Google und SO kann ich es nicht finden. Es könnte ein Fall sein, dass die richtigen Schlüsselwörter fehlen.Rails: halten DRY mit ActiveRecord-Modellen, die ähnliche komplexe Attribute teilen
In meiner RoR-Anwendung habe ich mehrere Modelle, die eine bestimmte Art von String-Attribut teilen, die spezielle Validierung und andere Funktionalität hat. Das ähnlichste Beispiel, das ich mir vorstellen kann, ist eine Zeichenfolge, die eine URL darstellt.
Dies führt zu vielen Duplizierungen in den Modellen (und noch mehr Duplizierung in den Komponententests), aber ich bin nicht sicher, wie man es DRYER macht.
ich von mehreren möglichen Richtungen denken kann ...
- ein Plugin nach dem Vorbild der „validates_url_format_of“ Plugin erstellen, aber das würde nur machen das Validierungen DRY
- dieses besondere geben string sein eigenes Modell, aber das scheint wie eine sehr schwere Lösung
- erstellen Sie eine Ruby-Klasse für diese spezielle Zeichenfolge, aber wie bekomme ich ActiveRecord, um diese Klassezuordnenmit dem Modell-Attribute, das eine Zeichenfolge in dem db
Nummer 3 scheint die vernünftigste Active ist, aber ich kann nicht herausfinden, wie zu erweitern, etwas anderes als die Basisdatentypen zu handhaben. Irgendwelche Zeiger?
Schließlich, wenn es eine Möglichkeit gibt, dies zu tun, wo in der Ordnerhierarchie würden Sie die neue Klasse, die kein Modell ist?
Vielen Dank.
UPDATE:
Eine mögliche Lösung unter Matts mixin Vorschlag mit (und dem URL-Beispiel verwenden). Beachten Sie, dass dies näher an psuedocode als an echtem Ruby liegt und eher das Prinzip als die perfekte Syntax vermitteln soll.
Erstellen Sie zunächst eine url
mixin:
module Url
def url_well_formed?
[...]
end
def url_live?
[...]
end
end
Und in einem Site
Modell, um diesen Modul:
Class Site < ActiveRecord:Base
include Url
validate :url_well_formed?
end
Und wenn ich, dass die Website unter der URL überprüfen muß, ist zu leben, tun ...
if site.url_live?
[...]
end
Die Sache, die das nicht löst, ist, wie man t macht Die Einheit testet DRY. Wenn ich ein anderes Modell verwende, z. B. Page
, das auch das Url
Mixin verwendet, benötigt es immer noch einen doppelten Satz von Komponententests für die URL. Natürlich könnte ich diese in einen Helfer stecken, aber das scheint chaotisch.
Gibt es eine grundlegendere Lösung, oder ist das so gut wie es geht?
Dank Matt. Ich kann sehen, wie Mixins mir einen Teil des Weges bringen (die Modelle selbst ziemlich trocken machen). Jetzt frage ich mich, wie ich die Unit-Tests auch DRY machen kann, aber das ist wahrscheinlich eine allgemeinere Frage, wenn Unit-Tests auf Module abgebildet werden. – Greg