Element 84 Logo

Precompiling Assets With Relative Paths in Rails 3.1

05.12.2012

We recently ran into an issue precompiling assets in Rails 3.1 for production. By default, Rails 3.1’s rake:assets:precompile task jams assets into a /assets directory. This works for simple deployments, but when deployed in Tomcat (or most application containers) some root context is applied to the application path.

For example – when running against rails server the URL to your application might look something like:

http://localhost:3000/users

When deployed, it might look something like:

http://localhost:10000/my-awesome-app/users

What you’ll find is your deployed app can’t find any assets since it’s looking in /assets and not /my-awesome-app/assets. You can read more about the issue here.

A quick solution is to use the rake task suggested by atambo that forces a relative path for your assets directory (from the issue thread):

namespace :assets do
  desc "Make all embedded assets in stylesheets relative paths"
  task :relativize => :environment do
    Dir[Rails.root.join("public/assets") + "*.css"].each do |asset|
      contents = File.read(asset)
      File.open(asset, "w") do |file|
        file.puts contents.gsub("url(/assets/", "url(")
      end
    end
  end
end

Add this rake task to your Rakefile and make sure to run it after precompiling your assets. It’s not ideal, but it’s a simple workaround for an issue that exists in Rails 3.1. It appears to have been fixed in 3.2 but updating Rails was not an option for us at the time.

Paul Pilone

Senior Software Engineer