Ich bekomme viel von Rails zurück, weil ich Benutzer in viele Unterklassen unterteilt habe. In meiner Anwendung sind nicht alle Benutzer gleich. Es gibt tatsächlich viele Modellobjekte und nicht jeder Benutzertyp hat Zugriff darauf.
Ich brauche auch einen Weg, polymorphes Verhalten zu machen. Zum Beispiel verhalten sich viele Methoden je nach Typ unterschiedlich. Ist das nicht der Polymorphismus?
Aber die Sache ist, ich werde immer wieder von Rails zurückgedrängt. Die Standardeinstellungen - insbesondere die Art und Weise, wie Formulare an Parameterhashes übergeben werden - scheinen wie nicht unterklassierte Modelle zu funktionieren. Links und Parameter-Hashes sind nur zwei Wege, auf denen die Standardeinstellungen Sie wirklich beißen.
Was ist der "richtige" Weg, komplexe Logik für verschiedene Arten von Benutzern in Rails zu behandeln? In Java funktioniert das Unterklassenmodell - Sie müssen nicht durch Rahmen gehen, damit es so funktioniert, wie Sie es möchten. In Rails ist es jedoch schwierig, Subklassen für die Verwendung von REST-Konventionen zu erhalten. Sie werden bestraft, wenn Sie :as => :user
vergessen haben, oder sie bestraft Sie, wenn Sie ein unterklassifiziertes Objekt in Links einfügen, z. B. edit_user_path(@user)
& lt; - schlechte Idee !
Es gibt noch einen anderen Bereich, mit dem man sich auch sehr schwer befassen kann. Angenommen, ich habe ein Company
-Modell und viele Users
. Diese Benutzer können Direktoren, Ausbilder, Auszubildende usw. sein - alle verschiedenen Unterklassen.
Wenn wir das Konto erstellen, möchten wir vielleicht accepts_nested_attributes_for :users
verwenden. Wenn wir dies jedoch verwenden, können wir die Klassen, die es erstellt, nicht angeben. Verdammte Hölle!
Es scheint so, als ob alles in Rails so entworfen wurde, dass Sie nicht möchten, dass Sie Ihre Modelle unterklassifizieren. Wenn Sie keine Unterklasse erstellen, "funktioniert" alles. Aber wenn Sie Unterklasse, Sie sind in der Hölle.
Was ist die Lösung?
Im Allgemeinen wird in Ruby die Vererbung zugunsten von Mixing-Verhalten und Delegierung abgelehnt. Ruby und Rails können das Zeug machen, aber es führt zu dem Push-back, den du erwähnt hast
Ihr konkretes Beispiel klingt nach einem Delegationsfall: Sie haben eine Benutzerklasse, die zu einem Mitarbeiter gehört (oder umgekehrt). Das typspezifische Verhalten dieses Mitarbeiters (z. B. Direktor, Ausbilder usw.) befindet sich in dieser speziellen Mitarbeiterklasse. Dann delegiert der Benutzer die Behandlung bestimmter Szenarien an den Mitarbeiter, mit dem er verbunden ist
Hier ist ein Trick, den ich herausgefunden habe. Gehen Sie nicht davon aus, dass es beabsichtigt ist:
%Vor% Grundsätzlich identifizieren sich alle Modelle (die von ActiveModel abgeleitet sind) standardmäßig anhand des konkreten Klassennamens. Dies geschieht über die Klassenmethode #model_name
(sie gibt eine Instanz von ActiveModel::Name
mit self
als Parameter zurück. Wenn Sie sie überschreiben, um eine bestimmte Klasse zurückzugeben, werden Rails auf die richtige Spur gesetzt. Auf diese Weise behalten Sie diese Logik in Ihrem Modell und aus Ihren Vorlagen.
Es geht im Grunde um "sag was du meinst",
Das Framework hat keine Möglichkeit zu wissen, wann Sie redirect_to @user
sagen, wenn Sie das generische Benutzerformular oder das spezialisierte Benutzerbenutzerformular gemeint haben.
Dies führt zu einer Menge von redirect_to @user.becomes(User)
, die du frei DRY up
und schreiben Sie redirect_to @user.to_b
, wenn Sie auf User
und nicht auf Employee
resource
Grundsätzlich stellt die elegante Syntax wie redirect_to @user
eine sehr tiefe Kopplung zwischen Modell und Ansicht / Controller dar, und wenn Sie die Modell- und Ansichts- / Controllerlogik zu komplexeren Rissen aufgrund dieser Kopplung machen, wird sich dies zeigen und einige zusätzliche Anstrengungen in der Domänentrennung müssen unternommen werden oder ein bisschen mehr Code muss geschrieben werden.
Rails bestraft Sie nicht für die Verwendung von OOP, Sie erleben eine erhöhte Komplexität von Modell & lt; - & gt; Ansicht & lt; - & gt; Controller-Beziehung:
Es war einmal deine Modellansicht und umgekehrt, jetzt hast du zwei Modellklassen, die zwei Ansichtsklassen zugeordnet sind, und wenn du eine Ansicht für das andere Modell verwenden willst, musst du es sagen
Tags und Links ruby ruby-on-rails subclassing model