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)
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.
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.
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 .
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With