2011-01-17 7 views

答えて

74

モデルにlink_toが必要な理由がいくつかあります。はい、@andy、それはMVCの違反ですが、それはあなたが質問に答えるためのポイントを取得する必要があるわけではありません。

@schwabsauce、それよりも簡単です。最初の行は、イニシャライザなどで行う場合には厳密には必要ありません。同じことが.sanitizeと.rawで機能し、他のすばらしい機能が満載です。

ActionView::Base.send(:include, Rails.application.routes.url_helpers) 
ActionController::Base.helpers.link_to(whatever) 

あなたがあなたのlink_toの内側にこれを実行する必要がありautopathsを使用する場合:

Rails.application.routes.url_helpers.page_path(@page) 
+0

この質問はもう少し前に聞かれましたが、その時点で@ andyのアドバイスが私にこの問題を解決する助けとなりました。しかし、実際の質問には答えられないという意味で正しいです。 – Krule

-6

ハッカーなし。

link_toがモデルに必要と思われる場合は、おそらくModel-View-Controller architectureの原理に違反している可能性があります。

モデルはデータとビジネスロジックの場所でなければなりませんが、リンクを生成することはコントローラやビュー(または、ヘルパークラスのRails)の仕事であることはほぼ確実です。

+1

ありがとう。ヘルパーを表示するように移動しました。すべてはすぐに収まります。 – Krule

+18

モデルでヘルパーを使用するのは十分な理由があります。しかし、もっと重要なことに、あなたがそれを考え抜いた場合に備えて、少なくともソリューションを提供するという意見を述べようとするならば。 2Kの担当者が頭をまっすぐにしている可能性があります。 –

5

私は、以下の介在物で動作するように、この得た:

include ActionView::Helpers::UrlHelper 
include ActionController::UrlFor 
include Rails.application.routes.url_helpers 

cattr_accessor :controller 
def controller; self.class.controller; end 
def request; controller.request; end 

その後、私のコントローラで、私は属性を埋め(ゼロからコントローラを作成するには、ハッシュ引数に大量のデータが必要です)。

Lead.controller = self 
+1

のために、Railsのドキュメントはこのソリューションへの道を進んでいます。 ActionDispatch :: Routing :: UrlForのドキュメントでは、ヒント:モデルや他の場所からURLを生成する必要がある場合、ActionController :: UrlForが探しているものです。そのファイルをインクルードすると、エラーメッセージとして表示されます。「#url_forを使用するには、ルーティングヘルパーを明示的にインクルードする必要があります」「たとえばRails.application.routes.url_helpersを含める」 場合によってはリンクを生成する最良の方法/最適な場所です: – schwabsauce

+0

たとえば、モデルがサードパーティのオフサイトゲートウェイへの支払い承認を処理していて、返品/キャンセルURLを生成する必要がある場合アプリに戻ります。 – hoffmanc

30

はあなたがRailsの3.2でこれをやっている場合は、チャックの記事で概説したアドバイス、以下の非常に注意してください。 1。このアプローチは、Rails 3.2.1の非ビュークラスのlink_toヘルパーを含めて安全な方法ではないように見えます。下記に概説するより安全な方法(いずれにしても私たちのために働く)があります。

私たちが私たちのクラスの1つでChuckの投稿でアプローチを使用したとき、結果は非常に困惑し、結果をデバッグするのが難しくなりました。それは非常に特殊な(そしてまれな)状況でしか見られなかった副作用/バグを引き起こしました。

問題、限り我々が言うことができるように、この行されていること:

ActionView::Base.send(:include, Rails.application.routes.url_helpers) 

ActionView::Baseは明らかにすでに独自に行いRails.application.routes.url_helpersを含むようにActionView::Baseを語っています。 url_helpersを2度追加すると、ルート状態(ActionDispatch :: Routing :: UrlForモジュールを含むクラスの@_routes)が再初期化されるようです。 url_helpers二度目含めた直接または間接的に、呼び出そうとするビューで例外、ActionView::Base後なurl_for方法

これは一見ランダムと原因不明の「NilClass nilのための 『なurl_for』未定義のメソッド」につながります。

url_helpersを再度記載する代わりに、UrlHelperモジュールを自分で含めてください。

次にあなたが(と仮定login_pathアプリに対して有効である)のlink_toを使用すると、あなたは、単にこれを行うことができますパスへのアクセス権を持っている必要がある場合:

include ActionView::Helpers::UrlHelper 
... 
link = link_to('here', Rails.application.routes.url_helpers.login_path) 

それは私たちに非常に長い時間がかかったし、非常に多く二重インクルードによって引き起こされたバグを追跡するためのヘッドスクラッチを作成しました.Railsの基本クラスの振る舞いを微調整するときに注意するように他の人に警告したかっただけです。

+0

共有していただきありがとうございます!私はあなたがより良い方法を見つけてうれしいです! –

+1

一行: 'ActionView :: Helpers :: UrlHelper'を含む – karlingen

+0

@karlingen - 'Rails.application.routes ...'への参照を省略すると、「url_forに渡された引数は処理できません。ルートを必要とするか、独自の実装を提供する " – Del

2

のlink_toヘルパー、アンディは言っMVC違反

あなたはおそらく、あなたがやって、なぜしているもので、大きくて長い見てみる必要があるモデルでHTMLを生成している場合。

URLヘルパーあなたならば、多くの場合であってもモデルで、サービス/フォーム/ APIのすべての種類/ ...例えばクラスでは、ビュー・コントローラのコードの便利な外に来る一方

のURLする必要がある。

はい、Rails.application.routes.url_helpersはモジュールですが、ゲイリーはそれを置くとして、それはあなただけのどこか面白いものを含まなければならないという意味ではありませんが起こって起動します:

https://www.destroyallsoftware.com/blog/2011/one-base-class-to-rule-them-all

何を行うことができます、あなたは次のとおりです。

delegate :url_helpers, :to => 'Rails.application.routes' 

してから使用し、例えば

url_helpers.home_url 
関連する問題