在我们当前的rails应用程序中,我们遵循某些模式来包含脚本和样式表等资源。
例如,一个这样的模式是(布局中的代码):
= stylesheet_link_tag controller.controller_name
这里的问题是,所有控制器都没有关联的样式表。检查资产是否存在的最佳方法是什么?具体来说,我知道由于缓存破坏资产名称,这里有一些技巧。
答案 0 :(得分:25)
最后想出了这个。资产存在可以检查如下:
YourApp::Application.assets.find_asset("#{asset}.css").nil?
答案是:
= stylesheet_link_tag controller.controller_name if YourApp::Application.assets.find_asset("#{controller.controller_name}.css")
答案 1 :(得分:13)
之前我找到了这个答案,我们很高兴在我们的应用程序中使用find_asset
(Rails 3.2.16),直到有一天它开始轰炸。
经过一番挖掘后,事实证明,即使在生产环境中,启用了资产预编译,第一次调用find_asset
也会尝试实际编译它正在寻找的资产,即使该资产已经预编译了。您可以想象,这不是好消息 - 在我们的具体情况下,我们将Compass库文件拉入样式表,该样式表在dev和预编译期间工作,但不在生产中,Compass不在资产负载中路径。
长话短说,find_asset
不是一种确定资产是否可以包含的防弹方式。您可以在有人试图提交此问题的问题中阅读更多相关信息,随后将其关闭为非{:3}}
确定资产是否存在以及在编译和预编译模式下工作的真正方法在上述问题的文件管理器需要跳过的环节中得到证明。这是他修复的差异:https://github.com/sstephenson/sprockets/issues/411
我把它放在这里,希望发现这一点的其他Google员工不会陷入同样的陷阱!
答案 2 :(得分:2)
要包含基于控制器名称
的资产<% controller_asset = controller.controller_name %>
<%= stylesheet_link_tag controller_asset if YourApp::Application.assets.find_asset(controller_asset) %>
根据控制器名称和操作名称包含资产(对我有用)
<% action_asset = "#{controller.controller_name}/#{controller.action_name}" %>
<%= stylesheet_link_tag action_asset if YourApp::Application.assets.find_asset(action_asset) %>
当然最好不要保留此代码,而是将其放在帮助器中。
答案 3 :(得分:0)
= stylesheet_link_tag controller.controller_name if File.exists?(File.join(Rails.public_path, 'assets', "#{controller.controller_name}.css"))
答案 4 :(得分:0)
这就是我自己使用的。将其添加到您的ApplicationHelper
:
module ApplicationHelper
def controller_stylesheet(opts = { media: :all })
if Rails.application.assets.find_asset("#{params[:controller]}.css")
stylesheet_link_tag(params[:controller], opts)
end
end
def controller_javascript(opts = {})
if Rails.application.assets.find_asset("#{params[:controller]}.js")
javascript_include_tag(params[:controller], opts)
end
end
end
并在application.html.haml
:
= controller_stylesheet
= controller_javascript
注意: 这适用于所有.js,.coffee,.css,.scss,即使它只是说.css和.js