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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

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

lookup_context.template_exists?("form", "posts", true)

Ответ 4

В 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

Ответ 5

Я знаю, что на это был дан ответ, и ему миллион лет, но вот как я закончил это для меня...

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

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

Ответ 6

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

<%=
  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 %> или некоторую производную, частичная может существовать, но вызывать исключение, которое будет тихо употребляться и стать источником боли для отладки.

Ответ 7

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

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