noizZze

Asset URLs and Paths in Rake Tasks

Sometimes you need to access an asset from a Rake task. One example is one of our projects where we need to compile a package for a Phonegap app that includes images, Javascript and CSS. Before Rails 3 and the Asset Pipeline we knew the location and the names of our assets exactly, but now they may be located anywhere and have the hashes in the names. Instead of recreating all the hashing and locating functionality, the most logical path is to reuse what’s there in Rails.

One way I figured is this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace :app do

  task :my_task => :environment do
    AppyTravels::Application.configure do
      config.assets.debug = false
      config.assets.digest = true
    end

    include AssetsMaster

    image_path('my_image.png')
  end

  # Assets master gives the access to helpers like #asset_path from rake tasks
  module AssetsMaster
    include Sprockets::Helpers::RailsHelper

    def config; Rails.application.config; end
    def controller; nil; end
    def relative_url_root; nil; end
  end

end

We have an AssetsMaster module that includes the Sprockets::Helpers::RailsHelper. This helper contains all path / url methods and some other asset-related goodness. Including this file would be sufficient in Rails 3.0, but it’s not in Rails 3.1+. In the latest version we need to have three more methods: config, controller and relative_url_root. The first one should refer to the app configuration, and the other two can be nil.

You may have noticed how I adjust the assets configuration in my Rake task (lines 4-6). As you can see, I disable debugging and enable digests explicitly to break the ties from the environment config.

After all this magic, you can finally enjoy your desired image_path helper that will obey Asset Pipeline configuration to the letter.

Comments