Rails im "/unterverzeichnis"

Wenn man eine Rails-Applikation in einem Unterverzeichnis bereitstellen will, sollte man zwei Aspekte berücksichtigen:
  • Die Generierung von Urls
  • Das Routing - das Handling der Urls ankommender Requests
Rails bietet hier verschiedene Möglichkeiten der Konfiguration, die je nach Kontext ideal kombiniert werden können.
Damit man valide Links etwa mit Linkhelpern generieren kann und Assets erwartungsgemäß eingebunden werden, muss die Rails-Application wissen wo sie sich befindet. Es ist also notwendig das Unterverzeichnis wie etwa "/app1" in der Konfiguration zu hinterlegen. In den Rails-Guides wird ein entsprechender Konfigurationschritt beschrieben:
config.relative_url_root = "/app1"

Link-Helper

Laut Guide (vgl. Rails-Guides) wird nun "/app1" den generierenerierten Links vorangestellt. Bei einer existierenden User-Resource und normal gescopten Routen gibt der Path-Helper users_path aber lediglich "/users" zurück und vom Url-Helper link_to(users) erhalten wir einen Link auf "localhost:3000/users". Wenn wir zusätzlich noch die Applikation in Rack::URLMap wrappen, die config.ru also folgendermaßen anpassen:
map Rails.application.config.relative_url_root do
  run Rails.application
end
gibt users_path nun "/app1/users" zurück, und der durch link_to(users) erzeugte Link zeigt auf "http://localhost:3000/app1/users".

Asset-Helper

Bleiben noch die Assets, für die auch Links durch diverse Helper generiert werden können. Um dies zu testen, haben wir eine Bild-Datei in /assets/images/ angelegt und versucht uns den Pfad dorthin generieren zu lassen. Mit den bisher vorgenommenen Konfigurationsschritten gibt uns der Asset-Helper image_path einen Pfad ohne "/app1" zurück und die Einbindung dieses Bildes mithilfe von Sass's Helper image-path führt auch nicht zum gewünschten Ergebnis. Dieses Verhalten bei der vorliegenden Konfiguration kann aber im Production-Environment Sinn ergeben, wenn für Assets ein gesondertes Routing vorgesehen ist. Um dieses Problem im Development-Environment zu lösen, könnte man die Anpassung in der config.ru rückgängig machen, nur dann liefern die Link-Helper nicht die gewünschten Ergebnisse. Stattdessen haben wir folgenden zusätzlichen Konfigurationsschritt in der application.rb vorgenommen:
config.action_controller.relative_url_root = "/app1"
Nun liefern auch alle Asset-Helper das gewünschte Ergebnis und die Bilder sind sichtbar.

relative_url_root_sample_app

Um die Konfigurationsmöglichkeiten und ihre Auswirkungen in verschiedenen Kombinationen zu betrachten, können Sie folgendes Repository auschecken:
git@git.taktsoft.com:hchun/relative_url_root_sample_app.git

Lesen Sie hierzu auch:
Rails Guides: deploy-to-a-subdirectory-relative-url-root
Stackoverflow: what-is-the-replacement-for-actioncontrollerbase-relative-url-root
rubydoc: URLMap
https://github.com/rack/rack/blob/1.5.2/lib/rack/urlmap.rb#L62
https://github.com/rails/rails/issues/4308

Zur Blog-Übersicht