Ruby on rails 3 在Rails中,如何在使用javascript_include_标记之前检查javascript文件是否存在
在rails 3.2应用程序中,在将javascript_include_标记包含到文件中之前,我想检查资产管道中是否存在javascript文件。比如:Ruby on rails 3 在Rails中,如何在使用javascript_include_标记之前检查javascript文件是否存在,ruby-on-rails-3,asset-pipeline,Ruby On Rails 3,Asset Pipeline,在rails 3.2应用程序中,在将javascript_include_标记包含到文件中之前,我想检查资产管道中是否存在javascript文件。比如: <% if javascript_file_exists? %> <%= javascript_include_tag "#{controller_name}_controller" %> <% end %> <%= javascript_include_tag params[:controll
<% if javascript_file_exists? %>
<%= javascript_include_tag "#{controller_name}_controller" %>
<% end %>
<%= javascript_include_tag params[:controller] if ::Rails.application.assets.find_asset("#{params[:controller]}.js") %>
我希望这样做,以便缺少javascript文件不会导致错误。有什么方法可以做到这一点吗?在Rails3.2中,您只需将js文件列表写在application.js文件的顶部即可。比如说,
//=require jquery.min
//=require jquery_ujs
//=require general
如果其中一个文件不存在(顺便说一句,将它们放在app/assets/javascripts上)-这不是问题,不会显示任何错误。虽然我知道application.js中的资产管道和清单,但我的方法是保持app的“基本”使用application.js中的javascript,并仅加载每个控制器的特定javascript
<%= javascript_include_tag "application" %>
<%= javascript_include_tag controller_name if File.exists?("#{Rails.root}/app/assets/javascripts/#{controller_name}.js") %>
在my application.html.erb的末尾
我知道这会导致浏览器再发出一个请求来获取特定于控制器的javascript,但可能在第一个请求之后,该javascript将被浏览器缓存。另一种方法是使用助手。这允许您检查文件的coffeescript或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]) %>
在应用程序布局中调用它:
<%= javascript_include_tag params[:controller] if javascript_exists?(params[:controller]) %>
最后编辑(可能):将其干燥
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
我知道这是一个很老的问题,但我建议使用find_asset函数。对于Rails 4,您可以执行以下操作:
<% if javascript_file_exists? %>
<%= javascript_include_tag "#{controller_name}_controller" %>
<% end %>
<%= javascript_include_tag params[:controller] if ::Rails.application.assets.find_asset("#{params[:controller]}.js") %>
Custom ViewHelpers来拯救我们!
将此添加到您的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
您可以在应用程序.html.erb
中这样使用它们:
<%= controller_stylesheet %>
<%= controller_javascript %>
注意:这适用于所有.js、.coffee、.css、.scs,即使它只是说.css和.js捕获错误:
#/app/helpers/application_helpers.rb
def javascript_include_tag_if_assets(*args)
javascript_include_tag(*args)
rescue Sprockets::Rails::Helper::AssetNotFound
''
end
或者,由于这要求在使用该方法之前进行检查,javascript\u include\u标记
使用javascript\u路径
,因此您不妨使用它进行检查,然后捕获该错误。这适用于所有类似javascript的资产。对于类似css的资产,请使用样式表\u路径
#/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
像…什么?你为什么需要它?解决了这个问题,增加了动力。谢谢因此,对于资产管道,每个控制器都会自动加载清单文件中指定的js文件,该文件与控制器同名。也就是说,users_controller.rb将加载users_controller.js?而且,您不需要在视图中指定javascript_include_标记?不,您必须将
/=require users.js
写入application.js。只有这样,才能访问users.js中的所有逻辑。只需将
放入布局即可。See@alex的方法会用这个users.js
重载每个视图。最好只执行上面的操作,然后询问Rails.application.assets是否存在该文件,如果要呈现该文件。我讨厌这样做,但这似乎是唯一可行的方法:(我找到了一个更好的方法。现在还没来得及发布它,但基本上都是关于Javascript资产的模块模式。这样,你就可以只包含application.js文件,并根据一些可以在布局中设置的data-*属性执行相应的模块。@hisa_py这实际上是一个非常糟糕的主意,因为它仍然为每个页面加载了很多不必要的JS(即使它没有执行)。分开的文件更好,即使Rails核心团队不这么认为。:)好主意。这可能取决于Rails的版本或我们的首选项,但对于4及以上版本,我会选择controller\u name
而不是params[:controller]
(还有action\u name
,因为特定于页面的js文件与操作的连接远大于控制器)。适用于最新的Ruby 2.2.1和Rails 4.2.3。如果需要,您甚至可以省略.js扩展名。默认模板不再添加.js(我的js文件现在只有.coffee扩展名)但是Rails在添加后仍然可以识别它。不应该使用params[:controller]
。而应该使用controller.controller\u name
,正如供参考的那样,这在Rails 6/Ruby 3上很好用。这在Rails 6中仍然有效/实用吗?@Jake你告诉我。我已经好几年没有使用Rails了。我现在是一名数据工程师。
#/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