The bug is mentioned in various places, such as
http://blog.ashchan.com/archive/2008/12/10/passengers-railsbaseuri-not-working/ and https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1946-setting-a-relative-root-url-via-a- and http://github.com/rails/rails/commit/a87462afcb6c642e59bfcd2e11e3351e2b718c38 .
The manual workaround (according to what is suggested on the pages above) is adding the line below to config/environments/production.rb:
config.action_controller.relative_url_root = '/myapp'We propose a completely automatic workaround here, which doesn't need hardcoding URIs to the Rails application configuration. To fix this, create a file config/initializers/!fix_relative_url_root.rb with the following contents:
# automatic relative_url_root fixIn addition to the fix above, here is another fix for url_for and redirect_to so they automatically prepend ActionController::Base.relative_url_root when they get a string starting with a slash. To apply the fix, create file config/initializers/!relative_url_for.rb with the following contents:
# for Phusion Passenger 2.2.2 and Rails 2.3.2 (>= 2.2.2)
# by pts@fazekas.hu at Mon May 4 20:48:38 CEST 2009
# from http://ptspts.blogspot.com/2009/05/how-to-fix-railsbaseuri-sub-uri-with.html
fail unless ActionController::Request # check loaded
module ActionController
class Request
def initialize(env)
@env = env # Rack::Request#initialize does only this
path = request_uri.to_s[/\A[^\?]*/]
sn = @env['SCRIPT_NAME']
if (RAILS_ENV == 'production' and
(sn.empty? or sn.starts_with?('/')) and
path == sn + @env['PATH_INFO'])
Base.relative_url_root = sn
end
end
end
end
# fix url_for and redirect_to to use ActionController::Base.relative_url_for
# fix for Rails 2.3.2
# by pts@fazekas.hu at Mon May 4 22:38:44 CEST 2009
# from http://ptspts.blogspot.com/2009/05/how-to-fix-railsbaseuri-sub-uri-with.html
fail unless ActionController::Base # check loaded
fail unless ActionView::Helpers::UrlHelper # check loaded
module ActionController
class Base
alias url_for__ptsroot__ url_for
def url_for(options = {})
options = Base.relative_url_root.to_s + options if
options.kind_of?(String) and options.starts_with?('/')
url_for__ptsroot__(options)
end
alias redirect_to__ptsroot__ redirect_to
def redirect_to(options = {})
options = Base.relative_url_root.to_s + options if
options.kind_of?(String) and options.starts_with?('/')
redirect_to__ptsroot__(options)
end
end
end
module ActionView
module Helpers
module UrlHelper
alias url_for__ptsroot__ url_for
def url_for(options = {})
return escape_once(
::ActionController::Base.relative_url_root.to_s + options) if
options.kind_of?(String) and options.starts_with?('/')
url_for__ptsroot__(options)
end
end
end
end
thanks a lot mate.
ReplyDeletealthough, I've noticed that you don't need to apply the fix for generating 'redirect_to' and 'url_for' properly.
Rails(2.3.2) generates the urls in a sub-url aware fashion as long as we set the Base.relative_url_root during start-up.
True.
ReplyDeleteBut, i was talkin about the second part of the dynamic fix.
dynamic_fix part#1
automatically sets the relative_url_root
dynamic_fix part#2
fixes url_for and reditect_to so they automatically prepend ActionController::Base.relative_url_root
what I meant to say was, with rails 2.3.2 we do not need to apply the part#2 of the dynamic fix. Part#1 is good enough. If we apply both the parts, then the relative url will be applied twice in your urls.
Thanks for the fix. I'm lovin deploying apps on sub-urls with passenger; makes demo deployments much more easier to manage.
Thanks for making your point clear that part #2 of the fix is not needed. But my experience is contrary to yours: I'm using Rails 2.3.2 with Phusion Passenger 2.2.2, and it doesn't work unless I apply both fixes.
ReplyDelete