Qual è la sostituzione di ActionController :: Base.relative_url_root?

Sto eseguendo il porting di un’app 2.x rails su rails3; lo chiameremo foo-app. Foo-app è una sezione di un’app più grande e vive in main_rails_app.com/foo-app. In precedenza, nella nostra configurazione di produzione di foo-app, impostiamo quanto segue per assicurarci che le nostre rotte per app-app funzionino correttamente:

ActionController::Base.relative_url_root = "/foo-app" 

Tuttavia, con rails3, ora ottengo:

 DEPRECATION WARNING: ActionController::Base.relative_url_root is ineffective. Please stop using it. 

Da allora ho cambiato la voce di configurazione di seguito:

 config.action_controller.relative_url_root = "/foo-app" 

Questo funziona principalmente in quanto tutte le chiamate a risorse esterne (javascript / css / images) useranno / foo-app. Tuttavia, nessuno dei miei percorsi cambia in modo appropriato, o in un altro modo, foo-app root_path mi dà ‘/’ quando mi aspetterei ‘/ foo-app’.

Due domande:

  1. Qual è la sostituzione di ActionController :: Base.relative_url_root
  2. se è config.action_controller.relative_url_root, allora perché i miei percorsi non riflettono il valore relativo_url_root impostato?

Dovresti essere in grado di gestire tutto ciò all’interno del file routes.rb. Avvolgi tutti i tuoi percorsi correnti nell’ambito; per esempio.

 scope "/context_root" do resources :controller resources :another_controller match 'welcome/', :to => "welcome#index" root :to => "welcome#index" end 

È quindi ansible verificare il routing tramite i rake routes che dovrebbero mostrare i percorsi di conseguenza, inclusa la root di contesto (relativa_url_root)

Se si distribuisce tramite Passenger, utilizzare la direttiva RackBaseURI : http://www.modrails.com/documentation/Users%20guide%20Apache.html#RackBaseURI

Altrimenti, puoi racchiudere l’istruzione run nel tuo config.ru con il seguente blocco:

 map ActionController::Base.config.relative_url_root || "/" do run FooApp::Application end 

Quindi devi solo impostare la variabile d’ambiente RAILS_RELATIVE_URL_ROOT su “/ foo-app”. Questo si applicherà anche alle rotte impostate in gemme o plugin.

Attenzione: non mescolare queste due soluzioni.

Mi sento come se dovessi complicarmi troppo e / o mancare qualcosa, ma questo problema mi ha frustrato per un po ‘ora, e qui ci sono i miei appunti.

Sommario

Esistono due problemi separati con due punti ciascuno per percorsi dinamici e statici:

  1. come ottenere il routing per abbinare correttamente un URL in arrivo
    • per le rotte
    • per file statici
  2. come generare URL che includono la relativa_root
    • tramite url helper
    • per beni statici

Un modo per risolvere tutti e quattro i punti:

  • Configura Nginx per rimuovere la porzione relative_root
    • Questo risolve la corrispondenza del percorso; scrivi solo percorsi che prevedono URL in / sviluppo simile
    • Anche i file statici sono serviti come in fase di sviluppo
  • Imposta la variabile di ambiente RAILS_RELATIVE_URL_ROOT
    • Ciò risolve generatori di risorse statiche
  • Utilizzare il middleware ScriptName seguito (modificarlo per utilizzare il valore dall’ambiente)
    • Ciò risolve gli helper users_path generati, ad es. users_path

Applicazione Wrapping the Rails in Rack :: URLMap in config.ru (risposta di Christoph)

 # config.ru map '/relative_root' do run Myapp::Application end 
  • richiede che l’URL in arrivo contenga la relativa_url_root (Nginx può essere configurato per rimuovere o mantenere questo, vedi sotto)
  • Rack accoda la relativa_url_root al rack env SCRIPT_NAME rack / urlmap.rb: 62
  • Rails aggiunge lo SCRIPT_NAME della richiesta corrente a url_for options metal / url_for.rb: 41
  • L’url_ di Rails antepone il nome dello script durante la generazione dei percorsi di routing / url_for.rb: 133

In modo che copra gli URL generati dagli helper users_path , ad es. Dato UserController , users_path sarà preceduto dalla relativa radice url.

Imposta SCRIPT_NAME nel middleware

 # config.ru class ScriptName def initialize(app, name) @app = app @name = name end def call(env) env['SCRIPT_NAME'] += @name @app.call(env) end end use ScriptName, '/relative_root' run Rails.application 
  • Ha lo stesso effetto di sopra, ma
  • Richiede che l’URL in entrata NON contenga la relativa_url_root

Impostazione RAILS_RELATIVE_URL_ROOT

  • il valore viene salvato in app.config.relative_url_root configuration.rb: 41
  • che a sua volta influenza i percorsi delle risorse asset_url_helper.rb: 137
  • ma è tutto ciò che vedo
  • in particolare non influenza gli helper dell’URL

Impostazione di config.action_controller.relative_url_root

  • ?? Può influire sulla compilazione delle risorse?
  • Sostituisce RAILS_RELATIVE_URL_ROOT env var?

Definizione esplicita di tutti i percorsi in /relative_root (risposta di rizzah)

 # config/routes.rb Myapp::Application.routes.draw do scope '/relative_root' do ... end end 
  • Gli helper Url genereranno gli URL corretti
  • L’URL in entrata deve contenere la radice dell’URL relativa (sensibile alla configurazione di Nginx, vedi sotto), altrimenti le eccezioni “nessuna route corrisponde”
  • Gli URL che richiedono risorse statiche, ad esempio /relative_root/images/logo.png eccezioni “nessuna corrispondenza di percorso”. Questo potrebbe non essere un problema se nginx sta comunque servendo asset statici.

Nginx config

Dato un config come questo:

 upstream myapp { server localhost:3000; } server { ... location /relative_root { proxy_pass http://myapp/; } } 

Nginx eliminerà la /relative_root e l’app Rails non la vedrà. Se hai bisogno dell’app Rails quindi proxy_pass , un modo è quello di cambiare la linea proxy_pass :

 ... proxy_pass http://myapp/relative_root/; ...