rake assets:precompile cannot be used with relative url root #2435

Closed
giga opened this Issue Aug 5, 2011 · 24 comments

Projects

None yet

9 participants

@giga

There is no way to tell the assets:precompile task that the application is deployed on a relative url root.
Trying to set RAILS_RELATIVE_ROOT does nothing, and setting config.action_controller.relative_url_root fails with undefined method `relative_url_root=' for ActionController::Base:Class.

@tenderlove
Ruby on Rails member

@josh how does the relative path get set for sprockets? Is is possible to use the relative root with precompile?

@josh josh was assigned Aug 8, 2011
@josh
Ruby on Rails member

relative_url_root is considered deprecated and has been superseded by Rack::URLMap style prefixing that handles SCRIPT_NAME shifting correctly.

The intent of relative_url_root was to prefix the entire app, which should include your static server. So even public/foo gets served from /prefix/foo. This means that you wouldn't want to prefix your assets again under app/assets/prefix or whatever.

Probably just needs to configure nginx to properly serve static files from the prefix too.

@josh josh closed this Aug 8, 2011
@giga

I'm sorry, I don't quite understand. My app is served by passenger with RackBaseUri /my-app

Inside the Rails app, asset_path renders /my-app/assets/blah, which is what I do want. But inside sass files, asset_path rendered by rake assets:precompile will be /assets/blah and thus will go 404.

From what I see in the code, there is no way to tell rake assets:precompile to generate files in the public/assets, with asset_path rendering /my-app/assets.

@giga
@giga

I'm sorry, maybe I'm not clear. What actually doesn't work is the asset_path function in sass files. It cannot know the SCRIPT_NAME since there is no request, and there is no way to set a replacement.

By the way, the relative_url_root method of ActionView::AssetPaths seems broken to me, it defines the config local variable and tries to call the method config.

@snelson

I was having an issue with AssetPath.relative_url_root when doing headless testing with Capybara and Capybara-Webkit. My CSS assets were failing to compile in test (seemingly when run on a rack test server), line 123 of action_view/asset_paths was throwing a whiny nil (undefined method 'action_controller' for nil). I've solved the problem temporarily by throwing this into an initializer, but not sure what the long term fix should be. I agree with @giga, this method seems broken to me too.

@josh should this be re-opened or should I create a new issue?

if Rails.env.test?
  module ActionView
    class AssetPaths
      private
      def relative_url_root
        ""
      end
    end
  end
end
@guilleiguaran guilleiguaran added a commit to guilleiguaran/rails that referenced this issue Sep 13, 2011
@guilleiguaran guilleiguaran Set relative url root in assets when controller isn't available for S…
…prockets. Fix #2435

See rails/sass-rails#42 for details
9279d11
@adamcrown

This was working for me in 3.1.1.rc1 after setting MyApp::Application.config.action_controller.relative_url_root =. But now in 3.1.1.rc2 running rake assets:precompile is back to generating /assets/... paths. Am I missing something or is there a regression in 3.1.1.rc2?

@spastorino
Ruby on Rails member

@adamcrown can you share an app that shows the issue with us?

@adamcrown

I should be able to post a not working app if need be but I think I've narrowed it down a bit and figured out what the problem is but I'm still not sure what the solution should be.

Here's what I found out:

d4f999f works.
f64a352 generates paths that include the relative_url_root but messes up the /assets part.
b479889 doesn't include the relative_url_root in the asset paths at all.

The reason it's broken seems to be because rake assets:precompile is no longer running any initializers which is where I was setting Rails.configuration.action_controller.relative_url_root. So I guess I just need to figure out somewhere else to set relative_url_root but I'm not quite sure where that should be. I'm going to dig into it further, but any help would be appreciated.

Once the dust settles on this it seems like some clear documentation on how to precompile assets for a relative_url_root really needs to find it's way into the guides somewhere. I'd be happy to submit a pull request to the guides but I want to make sure I've got this right myself.

@guilleiguaran
Ruby on Rails member

@adamcrown try adding it to your application.rb:

config.action_controller.relative_url_root = "example"

let me know if it's working

@adamcrown

@guilleiguaran I get

undefined method `relative_url_root=' for ActionController::Base:Class

when I try to set it in application.rb.

EDIT:
Actually, let me clarify that. I get the error when trying to run the server or console but now when I run rake assets:precompile

@guilleiguaran
Ruby on Rails member

@adamcrown try adding the same but to config/environments/production.rb

@josevalim
Ruby on Rails member

@josh i agree with you that people should stop using relative_url_root for requests, however, when you are generating assets routes for e-mails we need this information, which cannot be accessed at request.script_name. With that in mind, do we have other option besides bringing relative_url_root back?

Another option is to completely disregard relative_url_root for assets generation with sprockets and ask people to change their config.assets.prefix.

@josevalim
Ruby on Rails member

@guilleiguaran @adamcrown relative_url_root can only be set in rails through an environment variable. it is internal deprecated API. I am discussing with Josh a solution to this problem. we can either bring relative_url_root back or completely disable it for assets, forcing users to properly configure config.assets.prefix instead.

@adamcrown

@guilleiguaran setting relative_url_root in production.rb gives me the same the same "undefined method" error I got when setting it in application.rb.

@josevalim isn't config.assets.prefix used to set the asset directory to use within the /public directory and not the url root for the entire rails app? I guess I just don't see how "properly configuring config.assets.prefix" could be a replacement for relative_url_root.

Personally I'd be fine just using the RAILS_RELATIVE_URL_ROOT environment variable even for rake tasks like assets:precompile.

@guilleiguaran
Ruby on Rails member

@adamcrown setting RAILS_RELATIVE_URL_ROOT is working for you?

@adamcrown

@guilleiguaran RAILS_RELATIVE_URL_ROOT doesn't currently work. But I think it would be a reasonable alternative to the relative_url_root setting.

@josevalim
Ruby on Rails member

@adamcrown exactly. setting config.assets.prefix to "/my-app/assets" would make them be output to the proper place.

In any case, I guess we could expose Rails.application.config.relative_url_root because it is useful for scenarios we don't have a request (e-mail and precompilation). That could be done in few steps:

1) Adding relative_url_root to this list of configs here:

https://github.com/rails/rails/blob/master/actionpack/lib/abstract_controller/asset_paths.rb#L6

2) Ensure config.relative_url_root is passed to both ActionController and ActionMailer. The best place for that is here:

https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/railtie.rb#L31
https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/railtie.rb#L22

3) Ensure config.relative_url_root will default to the ENV["RAILS_RELATIVE_URL_ROOT"]. Default configuration values should be set here:

https://github.com/rails/rails/blob/master/railties/lib/rails/application/configuration.rb#L19

4) Adding a test case

@josevalim
Ruby on Rails member

Can someone at least provide a test case? Otherwise this probably won't make Rails 3.1.1.

@guilleiguaran
Ruby on Rails member
@adamcrown

I finally got a chance to check this out in Rails 3.1.1 final and it's working when setting RAILS_RELATIVE_URL_ROOT with the rake task. Not sure who fixed it but thanks.

@gerggggggg

This still doesn't seem to be working for me. I'm running rails 3.1.3 and running:

bundle exec rake assets:precompile RAILS_RELATIVE_URL_ROOT=foo

Specifically, I have a path to a background image in my styles.css.scss.erb file that I'm calling <%= asset_path "background_img.png" %> and the path that is generating is not getting the relative_url_root specified.

@josevalim
Ruby on Rails member

@guilleiguaran that test case will pass because it is inside a actionpack. A real test case should be created by adding it to railtie.

@guilleiguaran guilleiguaran reopened this Dec 12, 2011
@guilleiguaran
Ruby on Rails member

Fixed in #3946

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment