web-dev-qa-db-ja.com

パーシャルが存在するかどうかを確認するためのRails関数はありますか?

存在しないパーシャルをレンダリングすると、例外が発生します。レンダリングする前にパーシャルが存在するかどうかを確認し、存在しない場合は別のものをレンダリングします。 .erbファイルで次のコードを実行しましたが、これを行うにはもっと良い方法があるはずです。

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

現在、Rails 3/3.1プロジェクトで以下を使用しています:

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

私が見た他のソリューションに対する利点は、これがあなたのRails root。の代わりにすべてのビューパスを見るということです。これは私にとって多くのRailsエンジン。

これはRails 4。

97
Rein

私もこれに苦労していました。これは私が最終的に使用する方法です:

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

ビュー内から、template_exists?動作しますが、呼び出し規則は単一の部分的な名前文字列では動作せず、代わりにtemplate_exists?(name、prefix、partial)を取ります

パス上のパーシャルを確認するには:app/views/posts/_form.html.slim

つかいます:

lookup_context.template_exists?("form", "posts", true)
52
Luke Imhoff

Rails 3.2.13、コントローラーにいる場合、これを使用できます:

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

template_exists? でわかるように、AbstractController::ViewPathslookupcontextに委任されます。

_prefixesは、コントローラーの継承チェーンのコンテキストを提供します。

trueはパーシャルを探しているためです(通常のテンプレートが必要な場合は、この引数を省略できます)。

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

30
Flackou

私はこれが答えられており、100万年前であることを知っていますが、私がこれを私のために修正した方法は次のとおりです...

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で試したことがない)

8
afxjzs

私はこのパラダイムを多くの機会に使用して大成功を収めました。

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

上記のコードの利点は、特定の2つのケースを処理できることです。

  • パーシャルは確かに欠落しています
  • パーシャルは存在しますが、何らかの理由でエラーをスローしました

コードを使用する場合は<%= render :partial => "#{dynamic_partial}" rescue nil %>またはいくつかの派生物、パーシャルが存在する場合がありますが、静かに食べられ、デバッグの苦痛の原因になる例外が発生します。

5
br3nt

あなた自身のヘルパーはどうですか:

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