2015-10-09 10 views
23

プレゼンターなどの純粋なルビークラスで、Railsビューヘルパー(例:link_tocontent_tag)を使用するための「推奨」方法を研究しています。このフロントについてはほとんど情報がないようですが、Stackコミュニティが何を考えているのかを知りたいと思っていました。プレゼンテーションクラスでRailsビューヘルパーを使用するための推奨される方法

だから、我々が持っているオプションがあります。..手動

これはおそらく、最もクリーンである(私はRailsの4を使用しています注意してください、と以前のバージョンについてはあまり心配しています)

が必要なモジュールを含めます必要なヘルパーだけが含まれているからです。しかし、プレーンなRailsヘルパーで提供されている通常のビューコンテキストが現在のリクエストに対して設定されているため、このメソッドが動作しない場合があります。 url_forは現在のリクエストについてはわからないため、ホストが一致しない可能性があります。

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

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

使用ActionController::Base.helpers

レール3、ActionController::Baseは、現在のビューのコンテキストにアクセスするhelpers方法を含んでいるので。私は、この方法で提供されるビューコンテキストは、レールヘルパーのように構成されていると信じていますが、間違っている可能性があります。これについて実際には心配しているような文書はありませんが、実際にはうまくいきます。

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 

私はこのビューのコンテキストもincludeで混合することができると信じていますが、レールはヘルパーを表示する方法の数百を持っており、それが無差別にすべてを含めるように汚い感じています。

最後にプレゼンターを呼び出すとき、それは(render方法で、代替的に又は)初期化されていますとき

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 

個人的に私たちはただのクラスにビューコンテキストを渡すことができ、ビューコンテキストを注入後者の2つのオプションに傾いている傾向がありますが、Railsチーム(私が見つけることができた)からの決定的な回答がなく、私は少し不安を感じました。スタックよりも頼む方が良い!

答えて

5

Iは、第2及び第3の選択肢の組み合わせとなるだろう、何かのように:

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 

あなたの2番目のオプションは、多分良いオプションではありませんActionController::Base.helpersとしてスタブするためにすべてのあなたのユニットテストを必要とし、あなたの3番目のオプションでは、ちょうどいくつかのメソッドにアクセスするために大きなコンテキストを使用しています。

+0

Stubbingについての良い点' ActionController: :Base.helpers'、私はそれについて考えなかった。文法的には、これは最善のルートと思われます。ちょっとした研究の後で、私が使う最良の(view_context) '' view_context''は、コントローラやヘルパーがプレゼンターを呼び出すことで提供されるものだと思います。 – tombeynon

1

私は実際にはどのような方法を使用するかに依存しています。 content_tagなどのような基本的なものなら、私はActionController::Base.helpersの方法に行くだろう。いくつかのヘルパーを直接呼び出すこともできます(例:モデル内のパスについては、ほとんど常に、Rails.application.routes.url_helpers.comment_pathの行に沿って何かを使用します。

コントローラー固有のものについては、3番目のオプションが便利かもしれませんが、個人的には「純粋な」方法がよさそうです。ドレイパーは、あまりにも興味深いアプローチを持っている:彼らは、現在の要求のためにview_contextを保存し、それにh -helpersへの呼び出しを委任:https://github.com/drapergem/draper/blob/master/lib/draper/view_context.rb

それは本当に好みの問題だけです。すでに言ったように、私は一度にすべてのヘルパーを含むことはありません。しかし、DraperやCellsのような宝石を使わずに自分でプレゼンテーションレイヤーを構築したい場合は、2番目のオプションがとてもいいです。

+0

ルドルフありがとう、私はドレーパーを見ていた。興味深いのは彼らもコントローラ 'view_context'を使用していますが、過去にこの問題がたくさんあったようです - https://github.com/drapergem/draper/issues/124 – tombeynon