Lorsque je rend un partiel qui n'existe pas, j'obtiens une exception. Je voudrais vérifier si un partiel existe avant de le rendre et au cas où il n'existerait pas, je rendrai autre chose. J'ai fait le code suivant dans mon fichier .erb, mais je pense qu'il devrait y avoir une meilleure façon de le faire:
<% begin %>
<%= render :partial => "#{dynamic_partial}" %>
<% rescue ActionView::MissingTemplate %>
Can't show this data!
<% end %>
Actuellement, j'utilise ce qui suit dans mes projets Rails 3/3.1:
lookup_context.find_all('posts/_form').any?
L'avantage par rapport aux autres solutions que j'ai vues est que cela va regarder dans tous les chemins de vue au lieu de juste votre Rails root. Ceci est important pour moi car j'ai beaucoup de Rails moteurs.
Cela fonctionne également dans Rails 4.
Je me débattais aussi avec ça. C'est la méthode que j'ai finalement utilisée:
<%= render :partial => "#{dynamic_partial}" rescue nil %>
En gros, si le partiel n'existe pas, ne faites rien. Souhaitez-vous toutefois imprimer quelque chose si le partiel est manquant?
Edit 1: Oh, je n'arrive pas à comprendre la lecture. Vous avez dit que vous vouliez rendre quelque chose d'autre. Dans ce cas, qu'en est-il?
<%= render :partial => "#{dynamic_partial}" rescue render :partial => 'partial_that_actually_exists' %>
ou
<%= render :partial => "#{dynamic_partial}" rescue "Can't show this data!" %>
Modifier 2:
Alternative: vérification de l'existence du fichier partiel:
<%= render :partial => "#{dynamic_partial}" if File.exists?(Rails.root.join("app", "views", params[:controller], "_#{dynamic_partial}.html.erb")) %>
De l'intérieur d'une vue, template_exists? fonctionne, mais la convention d'appel ne fonctionne pas avec la chaîne de nom partielle unique, mais prend plutôt template_exists? (nom, préfixe, partiel)
Pour vérifier le chemin partiel: app/views/posts/_form.html.slim
Utilisation:
lookup_context.template_exists?("form", "posts", true)
Dans Rails 3.2.13, si vous êtes dans un contrôleur, vous pouvez utiliser ceci:
template_exists?("#{dynamic_partial}", _prefixes, true)
template_exists?
est délégué à lookupcontext
, comme vous pouvez le voir dans AbstractController::ViewPaths
_prefixes
donne le contexte de la chaîne d'héritage du contrôleur.
true
parce que vous recherchez un partiel (vous pouvez omettre cet argument si vous voulez un modèle standard).
Je sais que cela a été répondu et remonte à un million d'années, mais voici comment j'ai fini par résoudre ce problème pour moi ...
Rails 4.2
Tout d'abord, je mets cela dans mon 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
et maintenant au lieu d'appeler
<%= render "#{dynamic_path}" if lookup_context.find_all("#{dynamic_path}",[],true).any? %>
je viens d'appeler <%= render_if_exists "#{dynamic_path}" %>
j'espère que ça t'as aidé. (pas essayé dans Rails3)
J'ai utilisé ce paradigme à plusieurs reprises avec beaucoup de succès:
<%=
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
%>
L'avantage du code ci-dessus est que nous pouvons gérer des cas spécifiques de remorquage:
Si nous utilisons simplement le code <%= render :partial => "#{dynamic_partial}" rescue nil %>
ou un dérivé, le partiel peut exister mais déclenche une exception qui sera mangée silencieusement et deviendra une source de douleur à déboguer.
Qu'en est-il de votre propre assistant:
def render_if_exists(path, *args)
render path, *args
rescue ActionView::MissingTemplate
nil
end