Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 3 在Rails中,如何在使用javascript_include_标记之前检查javascript文件是否存在_Ruby On Rails 3_Asset Pipeline - Fatal编程技术网

Ruby on rails 3 在Rails中,如何在使用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

在rails 3.2应用程序中,在将javascript_include_标记包含到文件中之前,我想检查资产管道中是否存在javascript文件。比如:

<% 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