Include assets only if they exist

In our current rails application, we follow certain patterns to include assets such as scripts and style sheets.

For example, one such template (code inside the layout):

= stylesheet_link_tag controller.controller_name 

The problem is that not all controllers will have related stylesheets. What is the best way to check if an asset exists? In particular, I know that there is some kind of trickery here because of renaming assets in the cache.

+13
ruby-on-rails ruby-on-rails-3 asset-pipeline
Nov 21 '11 at 2:32
source share
5 answers
Finally invented it. The existence of assets can be verified as follows:
 YourApp::Application.assets.find_asset("#{asset}.css").nil? 

Then the answer will be as follows:

 = stylesheet_link_tag controller.controller_name if YourApp::Application.assets.find_asset("#{controller.controller_name}.css") 
+25
Nov 21 '11 at 19:44
source share

I found this answer earlier, and we happily used find_asset in our application (Rails 3.2.16) until one day it started to bomb.

After some digging, it turns out that even in a production environment with precompilation enabled, the first call to find_asset will actually try to compile the asset that it is looking for, even if this asset has already been precompiled. As you can imagine, this is not good news - in our particular case, we pulled out the Compass library file into a stylesheet that worked in dev and during pre-compilation, but not in production, where Compass was not in the asset loading path.

In short, find_asset not a bulletproof way to determine if an asset is available for inclusion. You can read a bunch more about this in a problem that someone was trying to report about it, and which was subsequently closed as not a bug: https://github.com/sstephenson/sprockets/issues/411

The real way to determine if an asset exists, and which works both in compilation and precompilation modes, is demonstrated in hoops so that the file of the above problems needs to be skipped. Here's the diff for fixing it: https://github.com/fphilipe/premailer-rails/pull/55/files

I put it here in the hope that the other Googlers who find it will not fall into the same trap as me!

+13
Mar 21 '14 at 17:56
source share

To enable a resource based on a controller name

 <% controller_asset = controller.controller_name %> <%= stylesheet_link_tag controller_asset if YourApp::Application.assets.find_asset(controller_asset) %> 

To enable an asset based on controller name and action name (was useful to me)

 <% action_asset = "#{controller.controller_name}/#{controller.action_name}" %> <%= stylesheet_link_tag action_asset if YourApp::Application.assets.find_asset(action_asset) %> 

And, of course, it’s better not to leave this code as it is, but rather put it in an assistant.

+2
Sep 04 '14 at 6:36
source share
 = stylesheet_link_tag controller.controller_name if File.exists?(File.join(Rails.public_path, 'assets', "#{controller.controller_name}.css")) 
0
Nov 21 2018-11-11T00:
source share

Simple ViewHelpers

This is what I use myself. Add this to your ApplicationHelper :

 module ApplicationHelper def controller_stylesheet(opts = { media: :all }) if Rails.application.assets.find_asset("#{params[:controller]}.css") stylesheet_link_tag(params[:controller], opts) end end def controller_javascript(opts = {}) if Rails.application.assets.find_asset("#{params[:controller]}.js") javascript_include_tag(params[:controller], opts) end end end 

and use them in your application.html.haml :

 = controller_stylesheet = controller_javascript 



Note. . This works with all .js ,. coffee, .css, .scss, although it just says .css and .js

0
Feb 04 '17 at 23:24
source share



All Articles