Включить активы только в том случае, если они существуют
В нашем текущем приложении rails мы следуем определенным шаблонам для включения таких активов, как скрипты и таблицы стилей.
Например, один такой шаблон (код внутри макета):
= stylesheet_link_tag controller.controller_name
Проблема заключается в том, что не все контроллеры будут иметь связанные таблицы стилей. Каков наилучший способ проверить, существует ли актив? В частности, я знаю, что здесь есть какая-то обманка из-за переименования активов в кэше.
Ответы
Ответ 1
Наконец, выдумал это. Существование активов можно проверить следующим образом:
YourApp::Application.assets.find_asset("#{asset}.css").nil?
Тогда ответ будет следующим:
= stylesheet_link_tag controller.controller_name if YourApp::Application.assets.find_asset("#{controller.controller_name}.css")
Ответ 2
Я нашел этот ответ раньше, и мы с радостью использовали find_asset
в нашем приложении (Rails 3.2.16), пока в один прекрасный день он не начал бомбить.
После некоторого копания получается, что даже в производственной среде с включенной предварительной компиляцией первый вызов find_asset
будет пытаться фактически скомпилировать актив, который он ищет, даже если этот актив уже был предварительно скомпилирован. Как вы можете себе представить, это нехорошая новость - в нашем конкретном случае мы вытаскивали файл библиотеки Compass в таблицу стилей, которая работала в dev и во время предварительной компиляции, но не в производстве, где Compass не был в загрузке активов путь.
Короче говоря, find_asset
не является пуленепробиваемым способом определить, доступен ли актив для включения. Вы можете прочитать кучу больше об этом в проблеме, которую кто-то пытался сообщить об этом, и который впоследствии был закрыт как не ошибка: https://github.com/sstephenson/sprockets/issues/411
Реальный способ определить, существует ли актив, и который работает как в режимах компиляции, так и в прекомпиляции, демонстрируется в обручах, чтобы файл вышеперечисленных проблем необходимо перескакивать. Здесь diff для его исправления: https://github.com/fphilipe/premailer-rails/pull/55/files
Я помещаю это здесь в надежде, что другие Гуглеры, которые найдут это, не попадут в ту же ловушку, что и я!
Ответ 3
Чтобы включить ресурс на основе имени контроллера
<% 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) %>
И, конечно, лучше не оставлять этот код так, как есть, а скорее помещать его в помощника.
Ответ 4
= stylesheet_link_tag controller.controller_name if File.exists?(File.join(Rails.public_path, 'assets', "#{controller.controller_name}.css"))
Ответ 5
Простые ViewHelpers
Это то, что я использую сам. Добавьте это в свой 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