在Rails中如何在使用javascript_include_tag之前检查javascript文件是否存在

Joh*_*ohn 6 ruby-on-rails-3 asset-pipeline

在rails 3.2应用程序中,我想在将javascript_include_tag包含在文件中之前检查资产管道中是否存在javascript文件.就像是:

<% if javascript_file_exists? %>
  <%= javascript_include_tag "#{controller_name}_controller" %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

我想这样做,以便缺少一个javascript文件不会导致错误.有没有办法做到这一点?

Wat*_*Box 17

更多Rails方法是使用帮助器.这允许您检查文件的coffeescript或javascript版本:

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

然后你可以在你的布局中使用它:

<%= javascript_include_tag params[:controller], :media => "all"  if javascript_exists?(params[:controller]) %>
Run Code Online (Sandbox Code Playgroud)

您可以使用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]) %>
Run Code Online (Sandbox Code Playgroud)


编辑:更新#javascript_exists?

我最近对我的javascript_exists?助手做了一些修改:

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
Run Code Online (Sandbox Code Playgroud)

在应用程序布局中调用它:

<%= javascript_include_tag params[:controller]  if javascript_exists?(params[:controller]) %>
Run Code Online (Sandbox Code Playgroud)

现在,这将处理更多扩展并使用注入来确定文件是否存在.然后,您可以根据应用的需要为扩展数组添加更多扩展.


编辑DEUX:更新了#stylesheet_exists?

相同,但对于样式表:

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
Run Code Online (Sandbox Code Playgroud)


编辑最后(可能):干掉它

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
Run Code Online (Sandbox Code Playgroud)


his*_*_py 7

虽然我知道资源管道和application.js中的清单,但我的方法是在app.js中保留app的"必需"javascript,并使用每个控制器的特定javascript加载

<%= javascript_include_tag "application" %> 
<%= javascript_include_tag controller_name if File.exists?("#{Rails.root}/app/assets/javascripts/#{controller_name}.js") %>
Run Code Online (Sandbox Code Playgroud)

在</ body>之前的application.html.erb的末尾

我知道这导致浏览器再发出一个请求来获取控制器特定的javascript,但也许在第一次请求之后,浏览器会缓存javascript.


Fer*_*bka 5

我知道这是一个非常古老的问题,但我建议使用find_asset函数.对于Rails 4,您可以执行以下操作:

<%= javascript_include_tag params[:controller] if ::Rails.application.assets.find_asset("#{params[:controller]}.js") %>
Run Code Online (Sandbox Code Playgroud)


ale*_*lex 0

在 Rails3.2 中,您所需要做的就是在application.js文件的顶部编写 js 文件列表。例如,

//=require jquery.min
//=require jquery_ujs
//=require general
Run Code Online (Sandbox Code Playgroud)

如果这些文件之一并不真正存在(顺便说一句,将它们放在 app/assets/javascripts 中) - 不是问题,不会显示任何错误。