Frage

Ich bin wirklich Rails genießen (obwohl ich in der Regel Restless bin), und ich genieße Rubin sehr OO zu sein. Dennoch ist die Tendenz riesige Subklassen Active zu machen und riesige Controller ganz natürlich ist (auch wenn Sie einen Controller pro Ressource verwenden, tun). Wenn Sie tiefe Objekt Welten zu schaffen sind, wo würden Sie die Klassen setzen (und Module, nehme ich an)? Ich bitte um Ansichten (in dem Helfer selbst?), Controller und Modelle.

Lib ist in Ordnung, und ich habe festgestellt, einige Lösungen, um es in einer Entwickler-Umgebung neu zu laden , aber ich würde gerne wissen, ob es ein besserer Weg, um diese Dinge zu tun. Ich bin wirklich nur Sorgen um Klassen zu groß wird. Und was ist Engines und wie sie passen?

War es hilfreich?

Lösung

Da Rails Struktur in Bezug auf MVC bietet, ist es natürlich, am Ende mit nur dem Modell, View und Controller Container, die für Sie zur Verfügung gestellt werden. Die typische Idiom für Anfänger (und sogar einige Zwischen Programmierer) ist die gesamte Logik in der App in das Modell (Datenbank-Klasse) zu stopfen, Controller oder Ansicht.

An einem gewissen Punkt, weist jemand aus dem „Fett-Modell, Skinny-Controller“ Paradigma und Zwischen Entwicklern in aller Eile alles von ihren Controllern auszuzuschneiden und sie in das Modell werfen, die für die Anwendungslogik eine neue Mülltonne zu werden beginnt.

Dünnen Controller sind in der Tat eine gute Idee, aber die logische Folge -. Alles im Modell setzt, ist nicht wirklich der beste Plan

In Ruby, haben Sie ein paar gute Möglichkeiten für die Dinge modular zu machen. Eine recht beliebte Antwort ist nur Module (in der Regel in lib verstaute), die Gruppen von Methoden halten, und dann sind die Module in die entsprechenden Klassen. Dies hilft bei Fällen, in denen Sie Kategorien von Funktionen, die Sie wollen in mehreren Klassen wieder zu verwenden, aber wo die Funktionalität noch fiktiv an die Klassen ist.

Denken Sie daran, wenn Sie ein Modul in eine Klasse gehören, werden die Methoden Instanzmethoden der Klasse, so dass Sie immer noch mit einer Klasse am Ende eine Tonne enthält, von Methoden, sind sie nur organisiert schön in mehrere Dateien.

Diese Lösung kann auch in einigen Fällen arbeiten - in allen anderen Fällen, Sie gehen über die Verwendung von Klassen in Ihrem Code zu denken, wollen, die nicht Modelle, Ansichten oder Controller.

Ein guter Weg, um darüber nachzudenken, ist die „einzige Verantwortung Prinzip“, die besagt, dass eine Klasse für eine einzelne (oder wenige) der Dinge verantwortlich sein sollte. Ihre Modelle sind verantwortlich für persistierenden Daten aus der Anwendung in die Datenbank. Ihre Controller sind verantwortlich für das Empfangen einer Anforderung und eine tragfähige Antwort zurück.

Wenn Sie Konzepte, die (Persistenz, Request / Response-Management) nicht ordentlich in diesen Kisten passen, möchten Sie wahrscheinlich darüber nachdenken, wie Sie würde Modell die Idee in Frage. Sie können speichern Nicht-Modellklassen in app / Klassen oder anderswo, und das Verzeichnis auf Ihren Lastpfad hinzufügen, indem Sie:

config.load_paths << File.join(Rails.root, "app", "classes")

Wenn Sie mit Passagier- oder JRuby, Sie wollen wahrscheinlich auch Ihren Weg zu den eifrigen Lastpfaden hinzuzufügen:

config.eager_load_paths << File.join(Rails.root, "app", "classes")

Die Bottom-Line ist, dass, wenn Sie in Rails zu einem Punkt, wo man sich diese Frage finden, ist es Zeit, Ihr Ruby-Koteletts, Rindfleisch und Modellierung von Klassen zu starten, das nicht nur die MVC-Klassen sind die Rails geben Sie durch Standard.

Update:. Diese Antwort gilt 2.x auf Rails und höher

Andere Tipps

Aktualisieren : Die Verwendung von Bedenken wurden bestätigt als neuer Standard in Rails 4 .

Es hängt wirklich von der Art des Moduls selbst. Ich in der Regel Controller / Modellerweiterungen in einem Ort / Bedenken Ordner innerhalb App.

# concerns/authentication.rb
module Authentication
  ...
end    

# controllers/application_controller.rb
class ApplicationController
  include Authentication
end



# concerns/configurable.rb
module Configurable
  ...
end    

class Model 
  include Indexable
end 

# controllers/foo_controller.rb
class FooController < ApplicationController
  include Indexable
end

# controllers/bar_controller.rb
class BarController < ApplicationController
  include Indexable
end

/ lib ist meine bevorzugte Wahl für allgemeine Bibliotheken. Ich habe immer einen Projekt-Namespace in lib, wo ich alle anwendungsspezifischen Bibliotheken setzen.

/lib/myapp.rb
module MyApp
  VERSION = ...
end

/lib/myapp/CacheKey.rb
/lib/myapp/somecustomlib.rb

Rubin / Rails Kernerweiterungen in der Regel statt in Config initializers so dass Bibliotheken nur einmal auf Rails Bootstrap geladen.

/config/initializer/config.rb
/config/initializer/core_ext/string.rb
/config/initializer/core_ext/array.rb

Für wiederverwendbare Codefragmente, habe ich oft erstellen (micro) Plugins, so dass ich sie in anderen Projekten wiederverwenden kann.

Helper-Dateien halten in der Regel Hilfsmethoden und manchmal Klassen, wenn das Objekt soll von Helfern verwendet werden (zB Formular-Builder).

Dies ist eine wirklich allgemeine Übersicht. Bitte geben Sie weitere Details über die spezifischen Beispiele, wenn Sie mehr individuelle Vorschläge erhalten möchten. :)

  

... die Tendenz zu machen riesige   Active Subklassen und riesig   Controller ist ganz natürlich ...

"große" ist ein Anlass zur Sorge Wort ...; -)

Wie werden Ihre Controller immer riesig? Das ist etwas, das Sie sehen sollten: Im Idealfall, Controller sollte dünn sein. Picking eine Regel-of-Daumen aus der Luft, würde ich vorschlagen, dass, wenn Sie regelmäßig mehr haben als, sagen wir, 5 oder 6 Zeilen Code pro Controller-Methode (Aktion), dann Ihre Controller sind wahrscheinlich zu dick. Gibt es Überschneidungen, die in eine Hilfsfunktion oder ein Filter bewegen könnte? Gibt es Geschäftslogik, die nach unten in die Modelle eingeschoben werden könnte?

Wie Sie Ihre Modelle erhalten riesig zu sein? Sollten Sie nach Wegen suchen, um die Anzahl der Aufgaben in jeder Klasse zu reduzieren? Gibt es gemeinsame Verhaltensweisen, die Sie in Mixins extrahieren kann? Oder Funktionsbereiche können Sie auf Hilfsklassen delegieren?

EDIT: Der Versuch, ein wenig zu erweitern, hoffentlich nichts zu schlecht zu verzerren ...

Helfer: leben in app/helpers und sind meist verwendeten Ansichten einfacher zu machen. Sie sind entweder steuerungsspezifische (auch für alle Ansichten für diesen Controller) oder allgemein verfügbar (module ApplicationHelper in application_helper.rb).

Filter: Sagen Sie bitte die gleiche Codezeile in mehreren Aktionen haben (oft, Abrufen eines Objekts mit params[:id] oder ähnliches). Das Duplizierung kann, indem er erklärt einen Filter in der Klassendefinition, wie before_filter :get_object zunächst auf ein separates Verfahren und dann aus den Aktionen völlig abstrahiert werden. Siehe Abschnitt 6 in der Action Rails-Führer deklarative Programmierung dein Freund sein lassen.

Refactoring-Modelle sind ein bisschen mehr von einer religiösen Sache. Jünger Uncle Bob wird vorschlagen, zum Beispiel, dass Sie die fünf Gebote von SOLID . Joel & Jeff kann eine, äh, „pragmatischen“ Ansatz empfehlen, obwohl sie schien zu sein, ein wenig später mehr in Einklang gebracht . Die Suche nach einer oder mehreren Methoden innerhalb einer Klasse, die auf einem klar definierten Teilmenge seiner Attribute arbeiten ist eine Möglichkeit, zu identifizieren Klassen, um zu versuchen, die aus Ihrem Active abgeleitete Modell Refactoring werden könnten.

Rails-Modelle haben keine Subklassen von Activerecord :: Base, übrigens zu sein. Oder um es anders auszudrücken, ein Modell muss nicht ein Analogon einer Tabelle, oder sogar im Zusammenhang mit irgendetwas überhaupt gespeichert. Noch besser ist, solange Sie Ihre Datei in app/models Namen nach Rails Konventionen (Call #underscore auf den Klassennamen, um herauszufinden, was Rails sucht), Rails, wird es finden, ohne dass requires notwendig ist.

Hier ist eine ausgezeichnete Blog-Post über die Fette Modelle Refactoring, die aus dem „Thin-Controller“ philosphy entstehen scheinen:

http: / /blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

Grund Nachricht ist, verwenden Serviceklassen statt "Do not Mixins von Fat Models Extract", der Autor liefert 7 Muster so tun

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top