Включить активы, только если они существуют - PullRequest
13 голосов
/ 21 ноября 2011

В нашем текущем приложении rails мы используем определенные шаблоны для включения ресурсов, таких как скрипты и таблицы стилей.

Например, один такой шаблон (код внутри макета):

= stylesheet_link_tag controller.controller_name

Проблема здесь в том, что не у всех контроллеров будут связанные таблицы стилей.Каков наилучший способ проверить, существует ли актив?В частности, я знаю, что здесь есть какая-то хитрость из-за того, что имена ресурсов для очистки кэша.

Ответы [ 5 ]

25 голосов
/ 21 ноября 2011

Наконец-то понял это. Наличие актива можно проверить следующим образом:

YourApp::Application.assets.find_asset("#{asset}.css").nil?

Тогда ответ будет:

= stylesheet_link_tag controller.controller_name if YourApp::Application.assets.find_asset("#{controller.controller_name}.css")
13 голосов
/ 21 марта 2014

Я нашел этот ответ раньше, и мы с радостью использовали find_asset в нашем приложении (Rails 3.2.16), пока однажды оно не начало бомбить.

После некоторого копания оказывается, что даже в производственной среде с включенной прекомпиляцией ресурса первый вызов find_asset попытается фактически скомпилировать искомый актив, даже если этот актив уже был предварительно скомпилирован. Как вы можете себе представить, это нехорошая новость - в нашем конкретном случае мы включили файл библиотеки Compass в таблицу стилей, которая работала в dev и во время прекомпиляции, но не работала, когда Compass не было в загрузке ресурсов путь.

Короче говоря, find_asset не является пуленепробиваемым способом определить, доступен ли актив для включения. Вы можете прочитать больше об этом в проблеме, которую кто-то пытался подать по этому поводу, и которая впоследствии была закрыта как ошибка: https://github.com/sstephenson/sprockets/issues/411

Реальный способ определить, существует ли актив и работает ли он как в режиме компиляции, так и в режиме прекомпиляции, демонстрируется в тех обручах, через которые должен был пройти файлер вышеуказанных проблем. Вот разница для его исправления: https://github.com/fphilipe/premailer-rails/pull/55/files

Я помещаю это здесь в надежде, что другие гуглеры, которые найдут это, не попадут в ту же ловушку, что и я!

2 голосов
/ 04 сентября 2014

Чтобы включить актив на основе имя контроллера

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

И, конечно, лучше не оставлять этот код таким, какой он есть, а поместить его в помощник.

0 голосов
/ 05 февраля 2017

Simple 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

0 голосов
/ 21 ноября 2011
= stylesheet_link_tag controller.controller_name if File.exists?(File.join(Rails.public_path, 'assets', "#{controller.controller_name}.css"))
...