Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add asset search paths to Sprockets based on a wildcard subdomain in rails 3.1?

The Rails Asset Pipeline guide instructs you to use config.assets.paths in config/application.rb but I don't have access to the request's subdomain at this point.

I'd like to be able to prepend an extra path (for the current request only) based on the request's subdomain.

My application specific details

It's a basic CMS app. The root domain.com host handles the administrative part with standard controller/view rendering and default asset paths.

Requests to subdomain.domain.com renders the site based on subdomain. It calls prepend_view_path in a before_filter and adds Rails.root.join('vendor/sites/[subdomain]/templates') for the current request only.

I'd like to be able to prepend Rails.root.join('vendor/sites/[subdomain]/assets') to the Sprockets search paths when the request host is [subdomain].domain.com.

EDIT

I ended up just dropping in a mixin for Sprockets::Environment that overwrites the call method:

module SiteAssetsResolver
  def call(env)
    begin
      # prepend path based on subdomain (from env)
      super # Sprockets::Server#call
    ensure
      # remove path based on subdomain
    end
  end
end

MyApp::Application.assets.extend(SiteAssetsResolver)
like image 200
Sean Huber Avatar asked Sep 21 '11 18:09

Sean Huber


People also ask

How do you Precompile rails assets?

To compile your assets locally, run the assets:precompile task locally on your app. Make sure to use the production environment so that the production version of your assets are generated. A public/assets directory will be created. Inside this directory you'll find a manifest.

What does rake assets Clean do?

rake assets:clean Only removes old assets (keeps the most recent 3 copies) from public/assets . Useful when doing rolling deploys that may still be serving old assets while the new ones are being compiled.

What is assets Precompile?

rails assets:precompile is the task that does the compilation (concatenation, minification, and preprocessing). When the task is run, Rails first looks at the files in the config.assets.precompile array. By default, this array includes application.js and application.css .


2 Answers

Just as you did for your view path, add a before filter and append the new path to Rails.application.config.assets.paths

I got this idea while watching Railscasts #279 Understanding the Asset Pipeline

like image 116
pedz Avatar answered Oct 13 '22 00:10

pedz


I agree with commenter on your question that said "The asset pipeline isn't really meant to be compiling your assets each request in production." -- making it not really possible to do exactly what you ask.

So how about an alternative to accomplish what you're really trying to accomplish here, which is different asset resolution for different subdomains. Put your sub-domain specific assets in sub-directories of your asset folders.

Now, in the view/helpers, when you call asset_path or any other helpers that take a relative asset path, ask it for "#{subdomain}/name_of_asset" instead of just "name_of_asset".

Now, because of the way the asset compiler works, it's possible this subdirectory method won't work, you may have to put the subdomain at the beginning of the actual filename instead. "#{subdomain}_name_of_asset". Not sure.

And this still wouldn't give you a sort of 'default fall through' where some assets in some subdomains don't have subdomain-specific assets, they just 'fall through' to the default. Which would be nice. It's possible a way can be figured out to do that too, not sure.

But at any rate, following this approach of asking for a different asset at display-time using logic in view/helper.... is going to get you further than your original suggested approach, which probably isn't possible.

like image 20
jrochkind Avatar answered Oct 12 '22 23:10

jrochkind