2015-10-09 17 views
23

Rails görüntü yardımcılarını (ör. link_to, content_tag) sunum yapan gibi düz bir yakut sınıfında kullanmak için 'önerilen' yöntemini araştırıyorum. Görünüşe göre bu cephede çok az bilgi var ve Stack topluluğunun ne düşündüğü hakkında bir fikir edinmek istedim.Önerilen kullanım yolları Rails bir sunum sınıfındaki yardımcıları görüntülüyor

Dolayısıyla, elimizde ne seçeneklerdir .. elle

Bu muhtemelen en temiz olduğu (I Rails 4 kullanıyorum not edin ve eski sürümleri hakkında daha az endişe duyuyorum)

gerekli modülleri dahil yol, sadece gerekli yardımcılar dahil olduğu için. Ancak, bu yöntemde, bazı durumlarda, normal Rails yardımcılarında sağlanan genel görünüm bağlamının geçerli istek için yapılandırıldığından çalışmamasını buldum. url_for, geçerli istek hakkında bilgi sahibi olmaz, böylece ana makine eşleşmeyebilir.

class MyPresenter 
    include ActionView::Helpers::UrlHelper 
    include ActionView::Helpers::CaptureHelper 

    def wrapped_link 
     content_tag :div, link_to('My link', root_url) 
    end 
end 

kullanımlar ActionController::Base.helpers

Raylar 3, ActionController::Base mevcut görünüm bağlamında erişmek için bir helpers yöntemi dahil etmiştir. Bu yöntemin sağladığı görüş bağlamının, bir ray yardımcısında olduğu gibi yapılandırıldığına inanıyorum, ama yanılıyor olabilirim. Bu konuda endişe verici görünen herhangi bir doküman yok ama pratikte gayet iyi çalışıyor.

class MyPresenter 
    def wrapped_link 
     h.content_tag :div, h.link_to('My link', h.root_url) 
    end 

    protected 

    def h 
     ActionController::Base.helpers 
    end 
end 

Ben bu görünüm bağlamı da include ile karıştırılabilir inanıyorum ama raylar yardımcıları görüntülemek yöntemlerin yüzlerce var ve gelişigüzel hepsini kapsayacak şekilde kirli hisseder.

Son olarak sunum çağrı zaman, (a render yöntemi alternatif olarak ya da) başlatıldı ne zaman

class MyPresenter 
    attr_accessor :context 
    alias_method :h, :context 

    def initialize(context) 
     @context = context 
    end 

    def wrapped_link 
     h.content_tag :div, h.link_to('My link', h.root_url) 
    end 
end 

class MyController < ApplicationController 
    def show 
     # WARNING - `view_context` in a controller creates an object 
     @presenter = MyPresenter.new(view_context) 
    end 
end 

Kişisel olarak sadece sınıf görünüşüdür bağlamı geçebileceği, görünüm bağlamında enjekte Son iki seçeneğe yönelme eğilimindedir, ancak Rails takımının kesin bir cevabı olmadan (bulabildiğim) biraz emin değildim. Yığından daha iyi kim sormak!

cevap

5

Ben ikinci ve üçüncü seçeneğin karışımı ile gider gibi bir şey:

class MyPresenter 
    def initialize(helpers) 
    @h = helpers 
    end 

    def wrapped_link 
    h.content_tag :div, h.link_to('My link', h.root_url) 
    end 

    private 
    attr_reader :h 
end 

İkinci seçeneğiniz belki iyi seçenek değildir ActionController::Base.helpers olarak stubbed için tüm birim testleri gerek duyuyorsanız ve Üçüncü seçenek sadece bazı yöntemlere erişmek için büyük bir bağlam kullanıyorsunuz.

+0

Stubbling 'hakkında iyi bir nokta ActionController: : Base.helpers', Bunu düşünmemiştim. Stilistik olarak bu, yapılacak en iyi yol gibi gözüküyor ve biraz araştırmadan sonra en iyi (yalnızca) view_context'in kullanılması gerektiğini düşünüyorum. – tombeynon

1

Bunu gerçekten kullandığınız yöntemlere bağlı olarak yapardım. Eğer sadece content_tag vb. Gibi temel unsurlarsa, ActionController::Base.helpers yoluna gidecektim. Bazı yardımcıları doğrudan aramak da mümkündür, örn. Modellerin içindeki yollar için neredeyse her zaman Rails.application.routes.url_helpers.comment_path satırlarında bir şey kullanırım.

Denetleyiciye özgü şeyler için üçüncü seçenek yararlı olabilir, ancak kişisel olarak "saf" yol daha iyi görünür. Draper çok ilginç bir yaklaşım vardır: https://github.com/drapergem/draper/blob/master/lib/draper/view_context.rb

Gerçekten sadece bir tercih meselesidir: Onlar buna h -helpers çağrıları temsilci ardından geçerli istek için view_context kaydedip. Daha önce de söylediğin gibi, tüm yardımcıları bir kerede asla eklemem. Ancak, sunum katmanı Draper veya Cells gibi bir mücevher kullanmadan kendiniz oluşturmak istiyorsanız ikinci seçenek oldukça güzel.

+0

Teşekkürler Rudolf, Draper'a da baktım. İlginç bir şekilde onlar da 'view_context' kontrolörünü kullanıyorlar, ancak geçmişte bu kadar çok sorun yaşadılar - https://github.com/drapergem/draper/issues/124 – tombeynon