Search code examples
ruby-on-railsruby-on-rails-3ruby-on-rails-3.1

Background image not showing in Rails 3.1 production


I have an issue with background images not showing up in production mode in a Rails 3.1 app (3.1.0.rc8). I'm also using sprockets 2.0.0 and passenger 3.0.8.

My stylesheet is .scss and uses image_tag('...') in the background section. When I deploy I am precompiling the assets.

My production server is using Apache2 with Passenger, with the application deployed to a sub URI. The virtual host is defined as:

ServerName wibble
DocumentRoot /srv/www
...
RailsBaseURI /myapp
<Directory /srv/www/myapp>
    Options -MultiViews
</Directory>

The application is actually deployed to /srv/applications/myapp and I've created a symbolic link from /srv/www/myapp to /srv/applications/myapp/current/public.

The stylesheet is being served correctly, but when I inspect the element for the logo it's coming up as:

url("http://wibble/assets/logo-xxx.png")

intead of:

url("http://wibble/myapp/assets/logo-xxx.png")

Actually, if I change the URL as above using edit declaration in Opera, it does show the logo correctly. This suggests to me that I'm referencing the image correctly, and it's being correctly precompiled. The actual stylesheet is fine so I'm also picking up the assets correctly. Just seems as if the RailsBaseURI is being missed out the url path.

I've tried all sorts in the stylesheet - using .erb, asset_path, /myapp/logo.png, myapp/logo.png - and nothing works. It all works fine in development mode with the thin server.

Any help will be greatly appreciated.


Solution

  • Finally I've come up with a couple of solutions.

    1) From https://github.com/rails/sass-rails/issues/17 it looks like this could get fixed in sass-rails. In the meantime I've monkey-patched helpers.rb 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 it's ok to embed images in the CSS, changing the stylesheet to have a .erb extension, and replacing the image-url('logo.png') with url(<%= asset_data_uri 'logo.png' %>) will work without any need to change sass-rails.