Search
Me

Developer for Forward. Former Technical Lead at ThoughtWorks.

Recent Comments
Elsewhere
« Copying Classes | Main | Meta-programming with instance_exec »
Thursday
08Nov2007

Watch out for the Monkey Patch

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+$/, '')
end

def javascript_path(source)
compute_public_path_for_packager(source, 'javascripts', 'js', false)
end

Beware the monkey patch.

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>