Kısmi olup olmadığını kontrol etmek için herhangi bir Rails işlevi var mı?


98

Varolmayan bir parçayı işlediğimde, bir İstisna alıyorum. Oluşturmadan önce bir kısmın var olup olmadığını kontrol etmek istiyorum ve yoksa başka bir şey oluşturacağım. .Erb dosyamda aşağıdaki kodu yaptım, ancak bunu yapmanın daha iyi bir yolu olması gerektiğini düşünüyorum:

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

1
Kullanan cevap rescuerisklidir. Kullanmadan önce diğer çözümlere bakardım.
Grant Hutchins

Yanıtlar:


98

Şu anda, Rails 3 / 3.1 projelerimde aşağıdakileri kullanıyorum:

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

Gördüğüm diğer çözümlere göre avantajı, bunun sadece ray kökleriniz yerine tüm görüş yollarına bakmasıdır. Çok sayıda raylı motorum olduğu için bu benim için önemli.

Bu aynı zamanda Rails 4'te de çalışır.


9
lookup_context.exists? ('posts / find') benim için çalışmadı. Bunun yerine, bu örnekte lookup_context.exists? (Ad, önek, kısmi) veya lookup_content.exists? ('Bul', 'gönderiler', doğru) kullandım.
Jenn

2
Bu, şablonları kontrol etmenin mevcut (raylar> = 3.2) yoludur (kaynak apidock )
maček

1
Kısmi, geçerli görünüm şablonuyla aynı klasördeyse, kullanabilirsiniz lookup_context.exists?("find", lookup_context.prefixes, true). Bu şekilde, görüşme dizinini çağrıya sabit kodlamanız gerekmez. Not, bu kısmi işlemler içindir. Kısmi olmayanlar için, son argümanı atlayın (veya doğru yerine yanlış kullanın)
Nathan Wallace

71

Ben de bununla mücadele ediyordum. Bu, kullandığım yöntem:

<%= render :partial => "#{dynamic_partial}" rescue nil %>

Temel olarak, kısmi mevcut değilse, hiçbir şey yapmayın. Kısmi eksikse bir şey yazdırmak ister miydiniz?

Düzenleme 1: Oh, okuduğunu anlamada başarısız oluyorum. Başka bir şey yapmak istediğini söyledin. Bu durumda, buna ne dersiniz?

<%= render :partial => "#{dynamic_partial}" rescue render :partial => 'partial_that_actually_exists' %>

veya

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

Düzenleme 2:

Alternatif: Kısmi dosyanın varlığını kontrol etme:

<%= render :partial => "#{dynamic_partial}" if File.exists?(Rails.root.join("app", "views", params[:controller], "_#{dynamic_partial}.html.erb")) %>

6
Sorum şu ki, bir anti-model olan akış kontrolünü yapmak için İstisnaları kullanmak istemiyorum: stackoverflow.com/questions/1546514/…
Daniel Cukier

6
Bir istisna, bir programın normal çalışmasının ötesinde gerçekleşen olayları işlemek için kullanılan bir akış denetimi türüdür. Dinamik kısmın orada olması bekleniyorsa, ancak bir şeyler ters giderse ve orada olmama ile sonuçlanırsa, bu bir istisna için makul bir kullanımdır (elbette IMO - istisnaların uygun kullanımı kutsal bir savaşın kendisidir). Alternatifinizin, gerçek dosyanın var olup olmadığını görmek için dosya sistemini kontrol etmek olduğunu söyleyebilirim. Cevabımı bu kodla güncelleyeceğim.
Jeff

3
Çözümü beğendim, yine de kısmi olarak atılan her türlü istisnayı yutuyor. IMHO bu, hataları izlemeyi zorlaştırır.
Matt

5
Farklı türde bir istisnanız varsa rescue nilve ... rescue ...yöntemleri bunu gizleyecektir. Bu, hata ayıklaması zor hatalara yol açar.
nicholaides

8
Bu çözümü gerçekten beğenmedim. kurtarmak pahalı ve File.exists? parçanın yalnızca bir yerde olabileceğini varsayar. @ Rein'in lookup_context kullanan çözümünün gitmenin yolu olduğuna inanıyorum.
Bert Goethals

52

Bir görünümün içinden şablon_ var mı? çalışır, ancak çağırma kuralı tek kısmi ad dizesiyle çalışmaz, bunun yerine template_exists? (ad, önek, kısmi) alır

Yoldaki kısmi kontrolü yapmak için: app / views / posts / _form.html.slim

Kullanım:

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

Rails 3.0.10'da app / views / posts / _foo.txt.erb gibi alternatif bir uzantıya sahipsem, bunu argümana şu şekilde eklemem gerektiğini buldum: template_exists? ("Foo.txt", "posts" , doğru)
Gabe Martin-Dempesy

Bu durum 3.2'de kullanımdan kaldırıldı
maček

Rails 3.2.x'te yetkilendirilmiş görünmüyor, ancak ikinci argüman bir önek dizisidir. Ayrıca, mevcut denetleyicide bulunur.
Brendan

2
Lookup_context.prefixes'i ikinci argüman olarak kullanabilirsiniz: lookup_context.template_exists? ("Form", lookup_context.prefixes, true)
lion.vollnhals

Bu bilgiye görünüm katmanından erişme açısından bu daha iyi bir cevaptır.
Brendon Muir

30

Rails 3.2.13'te, bir kontrol cihazındaysanız, bunu kullanabilirsiniz:

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

template_exists?lookupcontextgörebileceğiniz gibi , için yetki verildiAbstractController::ViewPaths

_prefixes denetleyicinin miras zincirinin bağlamını verir.

true çünkü bir kısmı arıyorsunuz (normal bir şablon istiyorsanız bu argümanı atlayabilirsiniz).

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


Olumlu oy verildi. Parametrelerin daha güncel ve daha iyi açıklaması.
jacobsimeon

4
Bir görünüm (örneğin bir düzen gibi) itibaren bu işleri: lookup_context.template_exists?("navbar", controller._prefixes, :partial). Bu bana, bu düzeni oluşturan mevcut şablonun belirtilen "navbar" kısmına sahip olup olmadığını ve eğer öyleyse onu işleyebileceğimi söyler. Ben geçmesi :partialo boolean ne olduğu hakkında açık ve net olması için sadece - :partialtruthy olduğunu. _prefixesBiraz için teşekkürler , @Flackou!
pdobb

Farklı bir üst dizinde bulunan bir parçayı arıyorsanız _prefixesile değiştirin nil.
ben

8

Bunun yanıtlandığını ve bir milyon yaşında olduğunu biliyorum, ama işte bunu benim için düzelttim ...

Raylar 4.2

Önce bunu application_helper.rb dosyama koydum

  def render_if_exists(path_to_partial)
    render path_to_partial if lookup_context.find_all(path_to_partial,[],true).any?
  end

ve şimdi aramak yerine

<%= render "#{dynamic_path}" if lookup_context.find_all("#{dynamic_path}",[],true).any? %>

sadece ararım <%= render_if_exists "#{dynamic_path}" %>

umarım yardımcı olur. (raylarda denemedim3)


1
Bir geri dönüş sağlamak istiyorsanız bu işe yaramaz. Ayrıca yerel değişkenleri de hesaba katmaz.
phillyslick

Bu tam olarak aradığım şeydi. Çok temiz cevap.
Güneşli

1
@BenPolinsky Sanırım def render_if_exists(*args); render(*args) if ...bunun için kullanabilirsiniz
siteler

6

Bu paradigmayı birçok durumda büyük bir başarıyla kullandım:

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

Yukarıdaki kodun yararı, belirli durumları ele alabilmemizdir:

  • Kısmi gerçekten eksik
  • Kısmi var, ancak bir nedenden dolayı bir hata attı

Sadece kodu <%= render :partial => "#{dynamic_partial}" rescue nil %>veya bir türevini kullanırsak, kısmi mevcut olabilir, ancak sessizce yenecek ve hata ayıklamak için bir acı kaynağı olacak bir istisna ortaya çıkarabilir.


4

Peki ya kendi yardımcınız:

def render_if_exists(path, *args)
  render path, *args
rescue ActionView::MissingTemplate
  nil
end
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.