In Rails how to check if javascript file exists before using javascript_include_tag

asset-pipeline, ruby-on-rails-3

Solution

A more Rails way is to use a helper. This allows you to check for a coffeescript or a javascript version of a file:

def javascript_exists?(script)
  script = "#{Rails.root}/app/assets/javascripts/#{params[:controller]}.js"
  File.exists?(script) || File.exists?("#{script}.coffee") 
end

Then you can use it in your layout:

<%= javascript_include_tag params[:controller], :media => "all"  if javascript_exists?(params[:controller]) %>

You can do the same with your CSS:

 -- helper --
 def stylesheet_exists?(stylesheet)
   stylesheet = "#{Rails.root}/app/assets/stylesheets/#{params[:controller]}.css"
   File.exists?(stylesheet) || File.exists?("#{stylesheet}.scss") 
 end

 -- layout --
 <%= stylesheet_link_tag params[:controller], :media => "all"  if stylesheet_exists?(params[:controller]) %>

EDIT: updated #javascript_exists?

I have recently made some changes to my `javascript_exists?` helper:

def javascript_exists?(script)
  script = "#{Rails.root}/app/assets/javascripts/#{script}.js"
  extensions = %w(.coffee .erb .coffee.erb) + [""]
  extensions.inject(false) do |truth, extension|
    truth || File.exists?("#{script}#{extension}")
  end
end

call it in the application layout:

<%= javascript_include_tag params[:controller]  if javascript_exists?(params[:controller]) %>

This will now handle more extensions and use an inject to determine if the file exists. You can then add a bunch more extensions to the extensions array, as needed for your app.

EDIT DEUX: Updated #stylesheet_exists?

Same, but for stylesheets:

def stylesheet_exists?(stylesheet)
  stylesheet = "#{Rails.root}/app/assets/stylesheets/#{stylesheet}.css"
  extensions = %w(.scss .erb .scss.erb) + [""]
  extensions.inject(false) do |truth, extension|
    truth || File.exists?("#{stylesheet}#{extension}")
  end
end

EDIT Last (probably): DRY it up

def asset_exists?(subdirectory, filename)
  File.exists?(File.join(Rails.root, 'app', 'assets', subdirectory, filename))
end

def image_exists?(image)
  asset_exists?('images', image)
end

def javascript_exists?(script)
  extensions = %w(.coffee .erb .coffee.erb) + [""]
  extensions.inject(false) do |truth, extension|
    truth || asset_exists?('javascripts', "#{script}.js#{extension}")
  end
end

def stylesheet_exists?(stylesheet)
  extensions = %w(.scss .erb .scss.erb) + [""]
  extensions.inject(false) do |truth, extension|
    truth || asset_exists?('stylesheets', "#{stylesheet}.css#{extension}")
  end
end

Problem

In a rails 3.2 app, I would like to check for the existence of a javascript file in the asset pipeline before including the javascript_include_tag in a file. Something like: ``` <% if javascript_file_exists? %> <%= javascript_include_tag "#{controller_name}_controller" %> <% end %> ``` I would like to do this so that the absence of a javascript file will not result in an error. Is there a way to do this?

Original source

Related problems