Broken precompiled assets in Rails 3.1 when deploying to a sub-URI?

Finally I've worked out a couple of workarounds/solutions.

Finally I've worked out a couple of workarounds/solutions. 1) From https://github. Com/rails/sass-rails/issues/17 it looks like this could get fixed in sass-rails.

I've monkey-patched helpers. Rb myself along the lines of the proposed patch in the link above. I simply set the required environment variable in the asset precompile line in deploy.rb.

I do all my monkey patching in a single file config/initializers/gem_patches.rb. In this file I patched this method as: module Sass module Rails module Helpers protected def public_path(asset, kind) path = options:custom:resolver. Public_path(asset, kind.

Pluralize) path = ENV'PRODUCTION_URI' + path if ENV'PRODUCTION_URI' path end end end end 2) Alternatively if you are ok to embed images in the CSS, changing the stylesheet to have a . Erb extension, and replacing the image-url("bg. Png") with url() will work without any need to change sass-rails.

Asset-data-uri doesn't exist as a pure Sass function so you have to use the Rails helper asset_data_uri.

Good shout on the second point - that would work and it's something I never considered. Definitely less than desirable, but a valid workaround. For point 1, could you clarify the setting of the variable in deploy.

Rb please? – Mark Embling Sep 10 at 18:25 I've just worked out what you mean... you're manually running the precompile task from your deploy. Rb file, right?

I'm using the supplied one by having added load 'deploy/assets' to my Capfile - so there's nowhere obvious in deploy. Rb where I should put the environment variable setting. I'm sure I can find somewhere else to set it though.

Even at worst, you've given me an issue to keep an eye on, at best I think it's the answer for right now. Thanks :) – Mark Embling Sep 10 at 18:43 Exactly. In my deploy.

Rb I have the asset precompile in an after "deploy:update_code" task. I do run "cd #{release_path}; bundle exec rake assets:precompile RAILS_ENV=production PRODUCTION_URI='/myapp'" and then in my monkey-patched helpers. Rb I just pick up ENV'PRODUCTION_URI'.

– Graeme McLean Sep 10 at 18:51 How (well where) did you do your monkey-patching? I seem to be failing with mine. – Mark Embling Sep 10 at 19:07 I've expanded my answer above with details of the patch.

– Graeme McLean Sep 10 at 19:29.

After a bit of digging around, I have found the issue. The issue is in Rails, specifically Sprockets::Helpers::RailsHelper::AssetPaths#compute_public_path. Sprockets::Helpers::RailsHelper::AssetPaths inherits from ActionView::AssetPaths and overrides a number of methods.

When compute_public_path is called through the Sass::Rails::Resolver#public_path method is sass-rails, the rails sprocket helper picks up the task of resolving the asset. Sprockets::Helpers::RailsHelper::AssetPaths#compute_public_path defers to super which is ActionView::AssetPaths#compute_public_path. In this method there is a condition of has_request?

On rewrite_relative_url_root as seen below: def compute_public_path(source, dir, ext = nil, include_host = true, protocol = nil) ... source = rewrite_relative_url_root(source, relative_url_root) if has_request? ... end def relative_url_root config = controller. Config if controller.

Respond_to?(:config) config ||= config. Action_controller if config. Action_controller.

Present? Config ||= config config. Relative_url_root end If you look at the internals of rewrite_relative_url_root it relies on a request to be present and the ability to derive it from the controller variable in order to resolve the relative url root.

The issue is that when sprockets resolves these assets for sass it does not have a controller present and therefore no request. The solution above didn't work in development mode for me. Here is the solution that I am using to make it work for now: module Sass module Rails module Helpers protected def public_path(asset, kind) resolver = options:custom:resolver asset_paths = resolver.context.

Asset_paths path = resolver. Public_path(asset, kind. Pluralize) if!

Asset_paths. Send(:has_request? ) && ENV'RAILS_RELATIVE_URL_ROOT' path = ENV'RAILS_RELATIVE_URL_ROOT' + path end path end end end end.

(perhaps a little less naively, not that the other approach caused me any issues...) – Mark Embling Sep 11 at 12:10 github. Com/rails/rails/pull/2977 – Nicholas Barthelemy Sep 11 at 19:29.

In the latest Rails 3.1.3 you need to monkey patch a different module now, for it to work This is what I did module Sprockets module Helpers module RailsHelper def asset_path(source, options = {}) source = source. Logical_path if source. Respond_to?(:logical_path) path = asset_paths.

Compute_public_path(source, asset_prefix, options. Merge(:body => true)) path = options:body? "#{path}?

Body=1" : path if! Asset_paths. Send(:has_request?) path = ENV'RAILS_RELATIVE_URL_ROOT' + path if ENV'RAILS_RELATIVE_URL_ROOT' end path end end end end And in my deploy.

Rb I have: desc "precompile the assets" namespace :assets do task :precompile_assets do run "cd #{release_path} && rm -rf public/assets/* && RAILS_ENV=production bundle exec rake assets:precompile RAILS_RELATIVE_URL_ROOT='/my_sub_uri'" end end before "deploy:symlink", "assets:precompile_assets.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions