Есть ли функция Rails, чтобы проверить, существует ли частичное? - PullRequest
96 голосов
/ 24 августа 2010

Когда я рендерим партиал, который не существует, я получаю исключение.Я хотел бы проверить, существует ли частичное перед рендерингом, и в случае, если он не существует, я сделаю что-то еще.Я сделал следующий код в моем файле .erb, но я думаю, что должен быть лучший способ сделать это:

    <% begin %>
      <%= render :partial => "#{dynamic_partial}" %>
    <% rescue ActionView::MissingTemplate %>
      Can't show this data!
    <% end %>

Ответы [ 7 ]

97 голосов
/ 18 ноября 2011

В настоящее время я использую следующее в своих проектах Rails 3 / 3.1:

lookup_context.find_all('posts/_form').any?

Преимущество перед другими решениями, которые я видел, состоит в том, что это будет выглядеть во всех путях просмотра, а не только в вашихкорни рельсов.Это важно для меня, так как у меня много рельсовых двигателей.

Это также работает в Rails 4.

69 голосов
/ 24 августа 2010

Я тоже боролся с этим. Это метод, который я в конечном итоге использовал:

<%= render :partial => "#{dynamic_partial}" rescue nil %>

По сути, если частичное не существует, ничего не делать. Хотели ли вы что-то напечатать, если часть отсутствует?

Редактировать 1: О, я не могу понять прочитанное. Вы сказали, что хотите сделать что-то еще. В таком случае, как насчет этого?

<%= render :partial => "#{dynamic_partial}" rescue render :partial => 'partial_that_actually_exists' %>

или

<%= render :partial => "#{dynamic_partial}" rescue "Can't show this data!" %>

Редактировать 2:

Альтернатива: проверка существования частичного файла:

<%= render :partial => "#{dynamic_partial}" if File.exists?(Rails.root.join("app", "views", params[:controller], "_#{dynamic_partial}.html.erb")) %>
52 голосов
/ 27 августа 2011

Из вида, template_exists? работает, но соглашение о вызовах не работает с единственной частичной строкой имени, вместо этого она принимает template_exists? (имя, префикс, частичный)

Чтобы проверить частичное на пути: приложение / просмотров / сообщений / _form.html.slim

Использование:

lookup_context.template_exists?("form", "posts", true)
30 голосов
/ 08 июня 2013

В Rails 3.2.13, если вы находитесь в контроллере, вы можете использовать это:

template_exists?("#{dynamic_partial}", _prefixes, true)

template_exists? делегировано lookupcontext, как вы можете видеть в AbstractController::ViewPaths

_prefixes дает контекст цепочки наследования контроллера.

true, потому что вы ищете частичное (вы можете опустить этот аргумент, если вы хотитеобычный шаблон).

http://api.rubyonrails.org/classes/ActionView/LookupContext/ViewPaths.html#method-i-template_exists-3F

8 голосов
/ 05 августа 2015

Я знаю, что на это уже ответили, и мне миллион лет, но вот как я в итоге исправил это для меня ...

Rails 4.2

Сначала я положил это в свойapplication_helper.rb

  def render_if_exists(path_to_partial)
    render path_to_partial if lookup_context.find_all(path_to_partial,[],true).any?
  end

и теперь вместо звонка

<%= render "#{dynamic_path}" if lookup_context.find_all("#{dynamic_path}",[],true).any? %>

я просто звоню <%= render_if_exists "#{dynamic_path}" %>

надеюсь, что это поможет.(не пробовал в рельсах3)

5 голосов
/ 16 февраля 2016

Я использовал эту парадигму много раз с большим успехом:

<%=
  begin
    render partial: "#{dynamic_partial}"
  rescue ActionView::MissingTemplate
    # handle the specific case of the partial being missing
  rescue
    # handle any other exception raised while rendering the partial
  end
%>

Преимущество приведенного выше кода состоит в том, что мы можем обрабатывать конкретные случаи:

  • Частичноедействительно отсутствует
  • Частичное существует, но по какой-то причине оно выдает ошибку

Если мы просто используем код <%= render :partial => "#{dynamic_partial}" rescue nil %> или некоторую производную, частичное может существовать, но вызываетисключение, которое будет молча съедено и станет источником боли при отладке.

4 голосов
/ 07 июля 2016

Как насчет вашего собственного помощника:

def render_if_exists(path, *args)
  render path, *args
rescue ActionView::MissingTemplate
  nil
end
...