Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix #3365. Default config.relative_url_root to ENV["RAILS_RELATIVE_URL_ROOT"]. #3946

Merged
merged 1 commit into from

8 participants

@pokonski

This pull request fixes generation of asset paths inside assets when deploying to sub-URI.
For example when our app is deployed inside /community this

/* app/assets/stylesheets/application.css.erb */
body{
  background: url(<%= image_path "bg.png" %>);
}

Now produces a proper path:

body{
  background: url(/community/assets/bg.png);
}

instead of /assets/bg.png.

Precompilation:

Also works!

RAILS_RELATIVE_URL_ROOT="/community" bundle exec rake assets:precompile
@guilleiguaran

Please can you rebase with master?

Github reports that this pull request cannot be automatically merged.

@guilleiguaran

My vote is +1 to this

@kennyj
Collaborator

+1
cool!! we'll close many issues.

@pokonski

I've made quite a mess. Can you try now?

@guilleiguaran

Now can be merged but you can squash your commits in one and force push (git push -f)? (to avoid have the "Merge master", "Merge conflict" and the repeated "Add a test case for RAILS_RELATIVE_URL_ROOT" commits)

A tutorial to do it: http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html

@pokonski

It's fixed now ;)

@guilleiguaran

Yeah, now it's great and ready to be merged :D

@josevalim josevalim merged commit af308ff into rails:master
@sergiocampama

Sorry, but with this am I still supposed to use config.assets.prefix? I thought that by only specifying config.relative_url_root in application.rb everything (routes, assets and everything) would detect that rails is running on a subfolder and react accordingly.

Is there any documentation as to how to really use a rails 3.2.1 app inside a subfolder?

@pokonski

@sergiocampama do you use Passenger? If so you don't need to configure config.assets.prefix. Only environmental variable is needed for precompiling assets.

@sergiocampama

no, i'm using nginx + thin

when precompiling, the assets get generated on the public folder? (I haven't really released my app yet, I'm only in development mode) if that's the case, then I see how it should work. But I still need config.assets.prefix in development mode, so that should go in environments/development.rb, right?

@pokonski

Once precompiled they land in public/assets. I don't know how you configured your nginx so can't help you precisely. But you should not touch config.assets.prefix at all.

http://guides.rubyonrails.org/configuring.html says:

config.action_controller.relative_url_root can be used to tell Rails that you are deploying to a subdirectory. The default is ENV['RAILS_RELATIVE_URL_ROOT']

Try and set that in environments/development.rb. Also notice the action_controller part, it's important.

@ndbroadbent

Hello, RAILS_RELATIVE_URL_ROOT is not working for me in Rails 3.2.2, with rake assets:precompile.

I have a file at assets/stylesheets/common.scss.erb, which contains the line:

background: url("<%= image_path "asterisk.gif" %>") ...

When I run bundle exec rake assets:precompile RAILS_RELATIVE_URL_ROOT='/sub_uri', the generated application.css contains background:url("/assets/asterisk.gif"), instead of background:url("/sub_uri/assets/asterisk.gif").

So, I want asterisk.gif to be copied to public/assets/asterisk.gif, but I need the URL to be /sub_uri/assets/asterisk.gif, since we use RailsBaseURI /sub_uri with Passenger.

Any help would be appreciated!

@pokonski

It should be:
RAILS_RELATIVE_URL_ROOT='/sub_uri' bundle exec rake assets:precompile

@ndbroadbent

Nope, I'm afraid that doesn't make a difference. Image paths are still missing /sub_uri

@ndbroadbent

I should mention that I have the following line in application.rb:

config.assets.initialize_on_precompile = false

I am not initializing the environment for asset precompiling, and I cannot because it crashes on Heroku when the production database is not configured.

@josevalim
Owner

Does it work if that configuration option is true on your local machine? If so, we have found the reason for the bug. Although I would suggest for you to configure it via config.relative_url_root instead of an environment variable.

@pokonski

Wait a second. So is it Passenger or Heroku?

@ndbroadbent

I'm afraid it's both... It's an open source application that needs to support all deployment strategies. So if a solution won't work for Heroku (without relative_url_root), then we can't use it with Passenger (with relative_url_root)

@ndbroadbent

@josevalim: Yes, it does work with config.assets.initialize_on_precompile = true.

@ndbroadbent

@josevalim - In recent versions of Rails, we were able to set config.assets.initialize_on_precompile = true without the production database configured, and assets:precompile didn't complain as long as we didn't autoload any models.

However, that seems to have changed in 3.2 - when Application.initialize! is called, it crashes instantly with the following backtrace:

rake aborted!
FATAL:  database "fat_free_crm_production" does not exist
/home/ndbroadbent/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/connection_adapters/postgresql_adapter.rb:1194:in `initialize'
/home/ndbroadbent/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/connection_adapters/postgresql_adapter.rb:1194:in `new'
... etc.
/home/ndbroadbent/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/connection_adapters/postgresql_adapter.rb:28:in `postgresql_connection'
/home/ndbroadbent/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:277:in `new_cshould I work on onnection'
/home/ndbroadbent/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:287:in `checkout_new_connection'
/home/ndbroadbent/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:142:in `connection'
/home/ndbroadbent/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.2/lib/active_record/model_schema.rb:308:in `clear_cache!'
... etc.
/home/ndbroadbent/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.2/lib/rails/initializable.rb:54:in `run_initializers'
/home/ndbroadbent/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.2/lib/rails/application.rb:136:in `initialize!'
/home/ndbroadbent/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.2/lib/rails/railtie/configurable.rb:30:in `method_missing'
/home/ndbroadbent/code/rails/fat_free_crm/config/environment.rb:5:in `<top (required)>'
...

What would you advise for my situation? Is it logical for Rails to support loading the environment without a database, or could Sprockets also handle the RAILS_RELATIVE_URL_ROOT env variable?

@andywenk

@ndbroadbent I hade the same issue . The problem is definitely

 config.assets.initialize_on_precompile = true

I removed it in config/environments/development.rb, set

 config.action_controller.relative_url_root = "/some_path"

and ran

 bundle exec rake assets:precompile RAILS_ENV=development

That worked for me.

@botimer

I am seeing on Rails 3.2.13 that config.assets.initialize_on_precompile = false causes config.relative_url_root to be omitted in compiled assets.

However, RAILS_RELATIVE_URL_ROOT from the environment is being applied to config.relative_url_root as expected. (You can also clearly set this manually.)

As mentioned above, config.action_controller.relative_url_root is the parameter that applies to the asset paths, so I have added one line to production.rb to restore the expected behavior:

config.action_controller.relative_url_root = config.relative_url_root
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
5 actionmailer/lib/action_mailer/railtie.rb
@@ -19,8 +19,9 @@ class Railtie < Rails::Railtie
options.stylesheets_dir ||= paths["public/stylesheets"].first
# make sure readers methods get compiled
- options.asset_path ||= app.config.asset_path
- options.asset_host ||= app.config.asset_host
+ options.asset_path ||= app.config.asset_path
+ options.asset_host ||= app.config.asset_host
+ options.relative_url_root ||= app.config.relative_url_root
ActiveSupport.on_load(:action_mailer) do
include AbstractController::UrlFor
View
2  actionpack/lib/abstract_controller/asset_paths.rb
@@ -4,7 +4,7 @@ module AssetPaths
included do
config_accessor :asset_host, :asset_path, :assets_dir, :javascripts_dir,
- :stylesheets_dir, :default_asset_host_protocol
+ :stylesheets_dir, :default_asset_host_protocol, :relative_url_root
end
end
end
View
1  actionpack/lib/action_controller/railtie.rb
@@ -31,6 +31,7 @@ class Railtie < Rails::Railtie
# make sure readers methods get compiled
options.asset_path ||= app.config.asset_path
options.asset_host ||= app.config.asset_host
+ options.relative_url_root ||= app.config.relative_url_root
ActiveSupport.on_load(:action_controller) do
include app.routes.mounted_helpers
View
3  railties/lib/rails/application/configuration.rb
@@ -9,7 +9,7 @@ class Configuration < ::Rails::Engine::Configuration
:cache_classes, :cache_store, :consider_all_requests_local,
:dependency_loading, :filter_parameters,
:force_ssl, :helpers_paths, :logger, :log_tags, :preload_frameworks,
- :reload_plugins, :secret_token, :serve_static_assets,
+ :relative_url_root, :reload_plugins, :secret_token, :serve_static_assets,
:ssl_options, :static_cache_control, :session_options,
:time_zone, :whiny_nils, :railties_order, :all_initializers
@@ -37,6 +37,7 @@ def initialize(*)
@cache_store = [ :file_store, "#{root}/tmp/cache/" ]
@railties_order = [:all]
@all_initializers = []
+ @relative_url_root = ENV["RAILS_RELATIVE_URL_ROOT"]
@assets = ActiveSupport::OrderedOptions.new
@assets.enabled = false
View
9 railties/test/application/assets_test.rb
@@ -478,6 +478,15 @@ class ::PostsController < ActionController::Base; end
assert_match 'src="//example.com/assets/rails.png"', File.read("#{app_path}/public/assets/image_loader.js")
end
+ test "asset paths should use RAILS_RELATIVE_URL_ROOT by default" do
+ ENV["RAILS_RELATIVE_URL_ROOT"] = "/sub/uri"
+
+ app_file "app/assets/javascripts/app.js.erb", 'var src="<%= image_path("rails.png") %>";'
+ add_to_config "config.assets.precompile = %w{app.js}"
+ precompile!
+
+ assert_match 'src="/sub/uri/assets/rails.png"', File.read("#{app_path}/public/assets/app.js")
+ end
private
Something went wrong with that request. Please try again.