是否有任何Rails函数来检查部分是否存在?
当我渲染一个不存在的部分时,我得到一个异常。我想在呈现它之前检查一个partial是否存在,如果它不存在,我会渲染其他东西。我做了我的.erb文件下面的代码,但我觉得应该有一个更好的办法来做到这一点:是否有任何Rails函数来检查部分是否存在?
<% 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?
的优势Ø我见过的解决方案是,这将看所有的视图路径,而不是只有你的rails根目录。这对我来说很重要,因为我有很多导轨引擎。
这也适用于Rails的4
lookup_context.exists?('posts/find')也可以工作 – 2012-03-07 03:50:23
lookup_context.exists?('posts/find')对我来说不起作用。相反,我使用lookup_context.exists?(名称,前缀,部分)或lookup_content.exists?('find','posts',true)。 – Jenn 2012-06-12 17:30:57
这是当前(rails> = 3.2)检查模板的方法(source [apidock](http://apidock.com/rails/ActionView/LookupContext/ViewPaths/template_exists%3F)) – 2012-12-11 20:47:35
我这个太挣扎。这是我结束使用的方法:
<%= 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")) %>
我的问题是,我不想使用异常来做流控制,这是一种反模式:http://stackoverflow.com/questions/1546514/java-exceptions-as-control-flow – 2010-08-26 13:46:46
异常是一种流量控制,用于处理超出程序正常运行的事件。如果动态部分应该在那里,但是出现了问题,并且最终不会出现,那么这对于例外来说是合理的使用(IMO当然 - 适当使用异常本身就是一场神圣的战争)。我会说你的选择是检查文件系统是否存在实际的文件。我会用该代码更新我的答案。 – Jeff 2010-08-26 20:08:28
我喜欢这个解决方案,但它会吞下部分中抛出的任何异常。恕我直言,这使得难以追查错误。 – Matt 2011-08-26 20:25:16
从视图中,template_exists?工作,但调用约定不适用于单个部分名称字符串,而是它需要template_exists?(名称,前缀,部分)
检查部分路径: app/views/posts/_form.html .slim
用途:
lookup_context.template_exists?("form", "posts", true)
On Rails 3.0.10我发现如果我有一个替代扩展名,比如app/views/posts/_foo.txt.erb,我需要将它添加到参数中:template_exists?(“foo.txt”,“posts “,true) – 2011-10-27 22:25:35
这在rails 3.2中已弃用 – 2012-12-11 20:45:51
它似乎没有在Rails 3.2.x中委派,但第二个参数是一个前缀数组。此外,它存在于电流控制器上。 – Brendan 2012-12-25 20:44:29
在Rails 3.2.13,如果你在一个控制器的时候,你可以使用这个:
template_exists?("#{dynamic_partial}", _prefixes, true)
template_exists?
委托给lookupcontext
,因为你可以见AbstractController::ViewPaths
_prefixes
给出了控制器继承链的上下文。
true
因为你正在寻找一个部分(如果你想要一个普通的模板,你可以省略这个参数)。
Upvoted。更新和更好地解释参数。 – jacobsimeon 2013-10-15 16:21:39
从一个视图(如布局),这个工作:'lookup_context.template_exists?(“navbar”,controller._prefixes,:partial)'。这告诉我当前渲染这个布局的模板是否具有声明的“navbar”部分,如果是,我可以渲染它。我通过':partial'来明确布尔是什么 - ':partial'是truthy。感谢'_prefixes'位,@Flackou! – pdobb 2013-12-20 20:31:08
如果您正在调用位于不同父目录中的部分,请将'_prefixes'替换为'nil'。 – ben 2015-05-01 19:39:58
我知道这已经回答了,是一个亿岁,但在这里就是我结束了我解决这个...
的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中)
如果您想提供回退功能,则这不起作用。 它也不考虑局部变量。 – phillyslick 2015-10-19 20:32:28
这正是我正在寻找的。非常干净的答案。 – Sunny 2016-03-03 16:20:38
@BenPolinsky我想你可以使用'def render_if_exists(* args);渲染(*参数)如果...' – juanpastas 2017-04-17 15:31:47
我已经使用这个模式上取得了巨大成功多次:
<%=
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 %>
或一些衍生物,部分可能存在,但引发一个异常,它将被默默地吃掉,并成为调试的痛苦之源。
你自己的助手什么:
def render_if_exists(path, *args)
render path, *args
rescue ActionView::MissingTemplate
nil
end
使用'rescue'是有风险的答案。在使用之前我会看看其他的解决方案。 – nertzy 2012-01-10 20:44:52