Rails 4: Rails-Modelle im Unterpfad ohne Namespace-Modelle organisieren?

80

Wäre es möglich, so etwas zu haben?

app/models/
app/models/users/user.rb
app/models/users/education.rb

Ziel ist es, den Ordner / app / models besser zu organisieren , ohne die Modelle mit einem Namespace versehen zu müssen.

Eine unbeantwortete Frage für Rails 3 lautet hier: Rails 3.2.9 und Modelle in Unterordnern .

Die Angabe von tabellenname mit Namespaces scheint zu funktionieren (siehe Rails 4-Modellunterordner ), aber ich möchte dies ohne einen Namespace tun .

Rubytastic
quelle
Ich habe verstanden, dass Sie keinen Namespace möchten, aber ich denke, der beste Weg, dies zu tun, ist die Verwendung von ActiveSupport Concerns.
Nando Sousa
2
@NandoSousa. Nein. ActiveSupport-Bedenken gelten für gemeinsames Verhalten. Wie Sie Modelle verwenden.
berkes

Antworten:

116

Standardmäßig fügt Rails dem Autoload-Pfad keine Unterordner des Modellverzeichnisses hinzu. Aus diesem Grund können nur Modelle mit Namespace gefunden werden - der Namespace beleuchtet das Unterverzeichnis, in das gesucht werden soll.

Fügen Sie config / application.rb Folgendes hinzu, um alle Unterordner von app / models zum Autoload-Pfad hinzuzufügen :

config.autoload_paths += Dir[Rails.root.join("app", "models", "{*/}")]

Oder, wenn Sie eine komplexere haben app / models Verzeichnis, das obige Verfahren von Ballung zusammen alle Unterordner von app / Modelle können nicht richtig funktionieren. In diesem Fall können Sie dies umgehen, indem Sie etwas expliziter vorgehen und nur die von Ihnen angegebenen Unterordner hinzufügen:

config.autoload_paths += Rails.root.join("app", "models", "<my_subfolder_name1>")
config.autoload_paths += Rails.root.join("app", "models", "<my_subfolder_name2>")

UPDATE für Rails 4.1+

Ab Rails 4.1 enthält der App-Generator config.autoload_pathsstandardmäßig keine . Beachten Sie also, dass das oben Genannte wirklich in config / application.rb gehört .

AKTUALISIEREN

Feste automatischer Laden Pfad Beispiele in dem obigen Code zu verwenden , {*/}statt {**}. Lesen Sie unbedingt den Kommentar von muichkine, um Einzelheiten dazu zu erfahren .

pdobb
quelle
6
Versuchte es, aber es schlägt fehl, wenn die Konstante User :: Credits nicht automatisch geladen werden kann. Es wird erwartet, dass /srv/books/app/models/user/credits.rb sie definiert. Die Dateien, die benannt werden sollen, sind also immer noch nicht beabstandet. Platzierte sie wie vorgeschlagen über dem lib-Eintrag.
Rubytastic
1
Dieser Fehler ist eigentlich eine gute Nachricht. Es bedeutet, dass die Datei gefunden wurde. Aber Sie verwenden hier eine seltsame Pluralisierung. Wenn Ihr Dateiname lautet, app/models/user/credits.rbstellen Sie sicher, dass der Klassenname in der Datei auch Plural ist : class Credits. Ich würde jedoch empfehlen, den Rails-Standard zu verwenden und ihn class Creditund den Dateinamen so zu gestalten app/models/user/credit.rb(Modelle sollten singulär sein). In jedem Fall sollte dies das Problem sein. Gib mir Bescheid!
pdobb
1
In Rails 4.1 Konfiguration verwende ichconfig.autoload_paths += %W( #{Rails.root}/app/models/namespace #{Rails.root}/app/models/other_namespace )
Epigene
14
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]funktioniert, verlangsamt aber die Anwendung, insbesondere im Entwicklungsmodus, in dem die App häufig neu geladen wird. Der Grund ist, dass Sie nicht alle Dateien zu den autoload_paths hinzufügen müssen, sondern nur die Stammordner, aus denen dann Dateinamen und Module abgeleitet werden können. In einfachen Worten, wenn Sie nur eine Ebene von Unterordnern in Modellen und keine Namespace-Modelle haben, sollten Sie config.autoload_paths += Dir[Rails.root.join('app', 'models', '*/')]nur die erste Ebene von Unterverzeichnissen hinzufügen. Gleiches für liboder andere Pfade.
Muichkine
3
@pdobb es ist Erfahrung :) Wenn Sie sich ansehen, wie das automatische Laden funktioniert, werden Sie sehen, dass es überhaupt Schleifen gibt, auto_loading_pathszu denen es die Inferenz für das Modell hinzufügt. Wenn Sie NameSpace::Modeles beispielsweise haben , wird versucht, in allen automatischen Ladepfaden a zu finden path/namespace/model. Dies kann natürlich nur übereinstimmen, wenn pathes sich um ein Verzeichnis handelt. Als Faustregel sollten Sie nur Verzeichnisse in haben, autoload_pathsum maximale Effizienz zu erzielen. Ich hoffe es hilft.
Muichkine