在 rails 3.2 应用程序中,我想在文件中包含 javascript_include_tag 之前检查资产管道中是否存在 javascript 文件。就像是:
<% if javascript_file_exists? %>
<%= javascript_include_tag "#{controller_name}_controller" %>
<% end %>
我想这样做,以便缺少 javascript 文件不会导致错误。有没有办法做到这一点?
在 rails 3.2 应用程序中,我想在文件中包含 javascript_include_tag 之前检查资产管道中是否存在 javascript 文件。就像是:
<% if javascript_file_exists? %>
<%= javascript_include_tag "#{controller_name}_controller" %>
<% end %>
我想这样做,以便缺少 javascript 文件不会导致错误。有没有办法做到这一点?
更 Rails 的方法是使用帮助程序。这允许您检查文件的咖啡脚本或 javascript 版本:
def javascript_exists?(script)
script = "#{Rails.root}/app/assets/javascripts/#{params[:controller]}.js"
File.exists?(script) || File.exists?("#{script}.coffee")
end
然后你可以在你的布局中使用它:
<%= javascript_include_tag params[:controller], :media => "all" if javascript_exists?(params[:controller]) %>
你可以对你的 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]) %>
编辑:更新#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
在应用程序布局中调用它:
<%= javascript_include_tag params[:controller] if javascript_exists?(params[:controller]) %>
这现在将处理更多扩展并使用注入来确定文件是否存在。然后,您可以根据应用程序的需要向 extensions 数组添加更多扩展。
编辑 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
编辑最后(可能):把它擦干
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
尽管我知道 application.js 中的资产管道和清单,但我的方法是将应用程序的“基本”javascript 保留在 application.js 中,并仅使用每个控制器加载特定的 javascript
<%= javascript_include_tag "application" %>
<%= javascript_include_tag controller_name if File.exists?("#{Rails.root}/app/assets/javascripts/#{controller_name}.js") %>
在 </body> 之前的 application.html.erb 末尾
我知道这会导致浏览器再发出一个请求以获取控制器特定的 javascript,但也许在第一个请求之后,该 javascript 将被浏览器缓存。
我知道这是一个很老的问题,但我建议使用 find_asset 函数。对于 Rails 4,您可以执行以下操作:
<%= javascript_include_tag params[:controller] if ::Rails.application.assets.find_asset("#{params[:controller]}.js") %>
将此添加到您的ApplicationHelper
:
module ApplicationHelper
def controller_stylesheet(opts = { media: :all })
if Rails.application.assets.find_asset("#{controller_name}.css")
stylesheet_link_tag(controller_name, opts)
end
end
def controller_javascript(opts = {})
if Rails.application.assets.find_asset("#{controller_name}.js")
javascript_include_tag(controller_name, opts)
end
end
end
你可以在你的application.html.erb
:
<%= controller_stylesheet %>
<%= controller_javascript %>
注意:这适用于所有 .js、.coffee、.css、.scss,即使它只是说 .css 和 .js
在 Rails3.2 中,您只需要在application.js文件的顶部写下您的 js 文件列表。例如,
//=require jquery.min
//=require jquery_ujs
//=require general
如果其中一个文件确实不存在(顺便说一句,将它们放在 app/assets/javascripts 中)- 没问题,不会显示任何错误。
捕捉错误:
#/app/helpers/application_helpers.rb
def javascript_include_tag_if_assets(*args)
javascript_include_tag(*args)
rescue Sprockets::Rails::Helper::AssetNotFound
''
end
或者,由于这要求在使用该方法之前进行检查,因此您不妨javascript_include_tag
使用javascript_path
它来检查然后捕获该错误。这适用于所有类似 javascript 的资产。对于类似 css 的资产,请使用stylesheet_path
.
#/app/helpers/application_helpers.rb
def javascript_include_tag_if_assets(*files, **opts)
files.each { |file| javascript_path(file) }
javascript_include_tag(*files, **opts)
rescue Sprockets::Rails::Helper::AssetNotFound
''
end