The project I’m currently working on uses both the Asset Packager and Distributed Assets to ensure we have only a few external assets, and that we can load assets across more than one host - all so that the pages for our site load nice and quick.
Unfortunately, wiring in the Asset Packager plugin caused the Distributed Assets plugin to break, and I spent an hour or two tracking it down yesterday. The cause? Asset Packager redefines the compute_public_path
method.
# rewrite compute_public_path to allow us to not include the query string timestamp # used by ActionView::Helpers::AssetTagHelper def compute_public_path(source, dir, ext=nil, add_asset_id=true) source = source.dup source << ".#{ext}" if File.extname(source).blank? && ext unless source =~ %r{^[-a-z]+://} source = "/#{dir}/#{source}" unless source[0] == ?/ asset_id = rails_asset_id(source) source << '?' + asset_id if defined?(RAILS_ROOT) and add_asset_id and not asset_id.blank? source = "#{ActionController::Base.asset_host}#{@controller.request.relative_url_root}#{source}" end source end
Distributed Assets works by chaining compute_public_path
- decorating the calculated path, adding the asset host prefix onto the url. But, Asset Packager works by defining the method into ActionView::Base
. So, when DistributedAssets::AssetTagHelper
is included with ActionView::Helpers::AssetTagHelper
, it chains a (now) hidden method.
But, the only places that use the new compute_public_path
code inside the Asset Packager Helper (which just avoids using the query string timestamp) is within Asset Packager itself.
So, I tweaked the implementation of AssetPackageHelper
to
def compute_public_path_for_packager(source, dir, ext, add_asset_id=true) path = compute_public_path(source, dir, ext) return path if add_asset_id path.gsub(/\?\d+$/, '')enddef javascript_path(source) compute_public_path_for_packager(source, 'javascripts', 'js', false) end
Beware the monkey patch.