Skip to content

Instantly share code, notes, and snippets.

@supertinou
Forked from ebeigarts/RAILS_RELATIVE_URL_ROOT.md
Last active August 29, 2015 14:19
Show Gist options
  • Save supertinou/aac10daff8f78b4573f7 to your computer and use it in GitHub Desktop.
Save supertinou/aac10daff8f78b4573f7 to your computer and use it in GitHub Desktop.

RAILS_RELATIVE_URL_ROOT

Rails

By default RAILS_RELATIVE_URL_ROOT is used only for asset pipeline.

To namespace your rails routes you need to wrap run MyApp::Application with map in your config.ru:

map ENV['RAILS_RELATIVE_URL_ROOT'] || "/" do
  run MyApp::Application
end

Make sure sprockets is up to date >= 2.2.2.backport1, had problems with older versions.

Gemfile (required only for rails 3.x):

gem 'sprockets', '2.2.2.backport1'

Now you can fire up the rails server using:

$ RAILS_RELATIVE_URL_ROOT=/sub rails server

If you change the RAILS_RELATIVE_URL_ROOT you need to make sure to rm -rf tmp/cache first.

ActionMailer

You will need to add :script_name to default_url_options in config/environments/*.rb:

config.action_mailer.default_url_options = { :host => 'localhost:3000', :script_name => Rails.application.config.relative_url_root }

Capistrano

In production you are probably precompiling assets, but they will not be prefixed with the url, the fastest way is just to symlink public/sub to public.

config/deploy.rb:

set :default_environment, {
  "RAILS_RELATIVE_URL_ROOT" => "/sub"
}

after "deploy:assets:precompile", "deploy:symlink_relative_public"

namespace :deploy do
  task :symlink_relative_public, :roles => :app do
    root_url = default_environment["RAILS_RELATIVE_URL_ROOT"]
    if root_url
      root_dir = root_url.split("/")[0..-2].join("/")
      run "mkdir -p #{latest_release}/public#{root_dir}" if root_dir.present?
      run "ln -nfs #{latest_release}/public #{latest_release}/public#{root_url}"
    end
  end
end

RSpec

By default tests will ignore RAILS_RELATIVE_URL_ROOT and if you want to make sure that tests work with /sub and there are no hard-coded paths in your app, you can fix this by creating spec/support/relative_url.rb

# http://stackoverflow.com/questions/5016690/making-rails-tests-aware-of-rack-middleware-outside-railss-internal-chain
Capybara.app = Rack::Builder.new do
  eval File.read(Rails.root.join('config.ru'))
end

# Fix route helpers in tests (e.g. root_path, ...)
module RelativeUrl
  extend ActiveSupport::Concern

  included do
    default_url_options[:script_name] = Rails.application.config.relative_url_root
  end
end

RSpec.configure do |config|
  config.include RelativeUrl, :type => :feature
end

Now you can run the specs using

$ RAILS_RELATIVE_URL_ROOT=/sub rspec
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment