Есть ли какая-либо функция 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