Welche schnelle Regel sollte ich in Ruby on Rails Development (oder MVC im Allgemeinen) befolgen, wo Logik platziert werden soll?
Bitte bejahen Sie dies - Mit Do setzen Sie dies hier , anstatt das nicht dort zu setzen .
Welche schnelle Regel sollte ich in Ruby on Rails Development (oder MVC im Allgemeinen) befolgen, wo Logik platziert werden soll?
Bitte bejahen Sie dies - Mit Do setzen Sie dies hier , anstatt das nicht dort zu setzen .
Antworten:
MVC
Controller : Geben Sie hier Code ein, der damit zu tun hat, was ein Benutzer möchte, zu entscheiden, was er ihm geben soll, ob er angemeldet ist, ob er bestimmte Daten sehen soll usw. Am Ende prüft der Controller die Anforderungen und ermittelt, welche Daten (Modelle) angezeigt und welche Ansichten gerendert werden sollen. Wenn Sie sich nicht sicher sind, ob Code in den Controller gelangen soll, sollte dies wahrscheinlich nicht der Fall sein. Halten Sie Ihre Controller dünn .
Ansicht : Die Ansicht sollte nur den Mindestcode für die Anzeige Ihrer Daten (Modell) enthalten, sie sollte nicht viel verarbeiten oder berechnen, sie sollte Daten anzeigen, die vom Modell berechnet (oder zusammengefasst) oder vom Controller generiert wurden. Wenn Ihre Ansicht wirklich eine Verarbeitung ausführen muss, die vom Modell oder Controller nicht ausgeführt werden kann, geben Sie den Code in einen Helper ein. Viel Ruby-Code in einer Ansicht macht das Seiten-Markup schwer lesbar.
Modell : In Ihrem Modell sollte sich der gesamte Code befinden, der sich auf Ihre Daten bezieht (die Entitäten, aus denen Ihre Website besteht, z. B. Benutzer, Post, Konten, Freunde usw.). Wenn Code Daten zu Ihren Entitäten speichern, aktualisieren oder zusammenfassen muss, geben Sie ihn hier ein. Es kann in Ihren Ansichten und Controllern wiederverwendet werden.
Um die Antwort von pauliephonic zu ergänzen:
Helfer : Funktionen zur Erleichterung der Erstellung der Ansicht. Wenn Sie beispielsweise immer eine Liste von Widgets durchlaufen, um deren Preis anzuzeigen, fügen Sie sie in einen Helfer ein (zusammen mit einem Teil für die tatsächliche Anzeige). Oder wenn Sie ein Stück RJS haben, das die Ansicht nicht überladen soll, legen Sie es in einen Helfer.
Das MVC-Muster befasst sich wirklich nur mit der Benutzeroberfläche und sonst nichts. Sie sollten keine komplexe Geschäftslogik in den Controller einfügen, da dieser die Ansicht, aber nicht die Logik steuert. Der Controller sollte sich mit der Auswahl der richtigen Ansicht befassen und komplexere Inhalte an das Domänenmodell (Modell) oder die Geschäftsschicht delegieren.
Domain Driven Design hat ein Service-Konzept, bei dem Sie die Logik festlegen, um eine Reihe verschiedener Objekttypen zu orchestrieren. Dies bedeutet im Allgemeinen Logik, die natürlich nicht zu einer Modellklasse gehört.
Ich stelle mir die Service-Schicht im Allgemeinen als API meiner Anwendungen vor. Meine Services-Layer entsprechen normalerweise ziemlich genau den Anforderungen der Anwendung, die ich erstelle. Daher dient der Service-Layer als Vereinfachung der komplexeren Interaktionen in den unteren Ebenen meiner App, dh Sie können das gleiche Ziel unter Umgehung der Service-Layer erreichen Aber Sie müssten viel mehr Hebel ziehen, damit es funktioniert.
Beachten Sie, dass ich hier nicht über Rails spreche. Ich spreche von einem allgemeinen Architekturstil, der Ihr spezielles Problem anspricht.
Perfekte Erklärungen hier schon, ein sehr einfacher Satz als Abschluss und leicht zu merken:
Wir benötigen SMART-Modelle, THIN-Controller und DUMB-Ansichten.
Der Rails-Weg besteht darin, dünne Controller und fette Modelle zu haben .
Legen Sie Dinge in Bezug auf Autorisierung / Zugriffskontrolle in den Controller.
Bei Modellen dreht sich alles um Ihre Daten. Validierung, Beziehungen, CRUD, Geschäftslogik
In Ansichten geht es darum, Ihre Daten anzuzeigen. Nur anzeigen und Eingaben abrufen.
Bei Controllern geht es darum zu steuern, welche Daten von Ihrem Modell zu Ihrer Ansicht (und welche Ansicht) und von Ihrer Ansicht zu Ihrem Modell gelangen. Controller können auch ohne Modelle existieren.
Ich stelle mir den Controller gerne als Sicherheitsbeamten / Empfangsmitarbeiter vor, der Sie als Kunden (Anfrage) an den entsprechenden Schalter weiterleitet, an dem Sie einem Kassierer (Ansicht) eine Frage stellen. Der Kassierer (Ansicht) geht dann und erhält die Antwort von einem Manager (Modell), den Sie nie sehen. Sie erhalten dann die Anfrage zurück zum Sicherheitsbeamten / Empfangsmitarbeiter (Controller) und warten, bis Sie angewiesen werden, zu einem anderen Kassierer (Ansicht) zu gehen, der Ihnen die Antwort gibt, die der Manager (Modell) ihnen als Antwort auf die Frage des anderen Kassierers (Ansicht) gegeben hat .
Wenn Sie dem Kassierer (Ansicht) etwas mitteilen möchten, geschieht weitgehend dasselbe, außer dass der zweite Kassierer Ihnen mitteilt, ob der Manager Ihre Informationen akzeptiert hat. Es ist auch möglich, dass der Sicherheitsbeamte / Empfangsmitarbeiter (Controller) Sie aufgefordert hat, eine Wanderung zu unternehmen, da Sie nicht berechtigt waren, dem Manager diese Informationen mitzuteilen.
Um die Metapher zu erweitern: In meiner stereotypen und unrealistischen Welt sind Erzähler (Ansichten) hübsch, aber mit leerem Kopf und glauben oft alles, was Sie ihnen sagen. Sicherheitsbeamte / Empfangsmitarbeiter sind minimal höflich, aber nicht sehr sachkundig, aber sie wissen, wo die Leute sollten und sollte nicht gehen und Manager sind wirklich hässlich und gemein, wissen aber alles und können sagen, was wahr ist und was nicht.
Eine Sache, die beim richtigen Trennen hilft, ist das Vermeiden des Anti-Patterns "Lokale Variablen vom Controller an das View übergeben". An Stelle von:
# app/controllers/foos_controller.rb:
class FoosController < ApplicationController
def show
@foo = Foo.find(...)
end
end
#app/views/foos/show.html.erb:
...
<%= @foo.bar %>
...
Versuchen Sie, es auf einen Getter zu verschieben, der als Hilfsmethode verfügbar ist:
# app/controllers/foos_controller.rb:
class FoosController < ApplicationController
helper_method :foo
def show
end
protected
def foo
@foo ||= Foo.find(...)
end
end
#app/views/foos/show.html.erb:
...
<%= foo.bar %>
...
Dies macht es einfacher zu ändern, was in "@foo" eingefügt wird und wie es verwendet wird. Es vergrößert die Trennung zwischen Controller und Ansicht, ohne sie komplizierter zu machen.
foo
und von @foo
ist derselbe - beide sind auf das Paar <ControllerClass, request> beschränkt. Darüber hinaus kann ich mithilfe der Getter-Version ändern, wie dieses Foo
Objekt gefunden / gespeichert / zwischengespeichert wird, ohne zu ändern, wie die Ansicht darauf zugreift.
Nun, es hängt irgendwie davon ab, womit sich die Logik befassen muss ...
Oft ist es sinnvoll, mehr Dinge in Ihre Modelle zu stecken und die Controller klein zu lassen. Dies stellt sicher, dass diese Logik problemlos von jedem Ort aus verwendet werden kann, an dem Sie auf die Daten zugreifen müssen, die Ihr Modell darstellt. Ansichten sollten fast keine Logik enthalten. Im Allgemeinen sollten Sie sich also bemühen, es so zu gestalten, dass Sie sich nicht wiederholen.
Ein kurzer Blick auf Google zeigt außerdem einige konkretere Beispiele dafür, was wohin geht.
Modell: Validierungsanforderungen, Datenbeziehungen, Methoden erstellen, Methoden aktualisieren, Methoden zerstören, Methoden finden (beachten Sie, dass Sie nicht nur die generischen Versionen dieser Methoden haben sollten, sondern auch, wenn Sie viel tun, z. B. Leute mit Rot finden Haare nach Nachnamen, dann sollten Sie diese Logik extrahieren, damit Sie nur den find_redH_by_name ("smith") oder ähnliches aufrufen müssen.
Ansicht: Hier sollte es um die Formatierung von Daten gehen, nicht um die Verarbeitung von Daten.
Controller: Hier geht die Datenverarbeitung hin. Aus dem Internet: "Der Controller hat den Zweck, auf die vom Benutzer angeforderte Aktion zu reagieren, alle vom Benutzer festgelegten Parameter zu übernehmen, die Daten zu verarbeiten, mit dem Modell zu interagieren und die angeforderten Daten in endgültiger Form an den Benutzer weiterzuleiten Aussicht."
Hoffentlich hilft das.
In einfachen Worten, Modelle haben im Allgemeinen alle Codes, die sich auf Tabellen beziehen, ihre einfachen oder komplexen Beziehungen (denken Sie an SQL-Abfragen mit mehreren Tabellen) und die Manipulation der Daten / Variablen, um mithilfe der Geschäftslogik zu einem Ergebnis zu gelangen .
Controller verfügen über Code / Zeiger auf die relevanten Modelle für den angeforderten Job.
Ansichten akzeptieren die Benutzereingaben / Interaktionen und zeigen die resultierende Antwort an.
Jede größere Abweichung von diesen wird diesen Teil unerwünscht belasten und die Gesamtleistung der Anwendung kann beeinträchtigt werden.
Testen, Testen ... Wenn Sie so viel Logik wie möglich in das Modell einfügen, können Sie es ordnungsgemäß testen. Unit-Tests testen die Daten und die Art und Weise, wie sie durch Testen des Modells gebildet werden, und Funktionstests testen die Art und Weise, wie sie durch Testen der Controller geroutet oder gesteuert werden. Daraus folgt, dass Sie die Integrität der Daten nur testen können, wenn sie vorhanden sind das Model.
j