有没有Rails的function来检查是否存在一个部分?

当我渲染一个不存在的部分时,我得到一个exception。 我想在渲染之前检查一个partial是否存在,如果它不存在,我会渲染其他东西。 我在我的.erb文件中做了下面的代码,但我认为应该有一个更好的方法来做到这一点:

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

目前,我在Rails 3 / 3.1项目中使用了以下内容:

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

我已经看到的其他解决scheme的优势是,这将在所有视图path,而不是只有你的rails根。 这对我来说很重要,因为我有很多导轨引擎。

这也适用于Rails 4。

我也在为此苦苦挣扎。 这是我最终使用的方法:

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

从视图中,template_exists? 工作,但调用约定不适用于单个部分名称string,而是需要template_exists?(名称,前缀,部分)

检查部分path:app / views / posts / _form.html.slim

使用:

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

在Rails 3.2.13中,如果你在一个控制器中,你可以使用这个:

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

template_exists? 被委派给lookupcontext ,就像你在AbstractController::ViewPaths看到的AbstractController::ViewPaths

_prefixes给出了控制器inheritance链的上下文。

true因为你正在寻找一个部分(如果你想要一个普通的模板,你可以省略这个参数)。

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

我知道这已经回答了,已经有一百万年了,但是这里是我如何最终为我解决这个问题。

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中试过)

我曾多次使用过这个范例,取得了巨大的成功:

 <%= 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 %>或者一些派生的话,partial就可能存在,但是会引发一个exception,这个exception会被默默地吃掉,成为debugging的痛苦之源。

你自己的帮手呢?

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