web-dev-qa-db-ja.com

Railsのコントローラーからmixinしてlink_toを呼び出す方法は?

これはnoobの質問のようですが、簡単な答えは私を逃れています。 HTMLリンクを吐き出すには、ActionControllerメソッドでlink_toを呼び出す必要があります。 ActionView::Helpers::UrlHelper.link_tourl_forを呼び出しますが、これはコントローラーではなくAVモジュールのバージョンを呼び出します。私はこれを何とかして私が意図したことをするように強制することができました

  #FIXME there must be a better way to mixin link_to
  alias_method :self_url_for, :url_for
  include ActionView::Helpers::UrlHelper
  alias_method :url_for, :self_url_for

コントローラで。しかし、それが正確に機能する理由はまだわかりません。誰かがメソッドのスコープとここで起こっていることを隠すことを説明してもらえますか? link_to(または一般的に、モジュールの一部のメソッドのみを含める)を混合してコントローラーで呼び出すことができるより良い方法は何ですか(リンクを使用してフラッシュ文字列を生成するのがユースケースです)。

MVCに関する講義はありません。もしあれば、link_tourl_forとは別のモジュールにある必要があります。これに関するノイズの量から判断すると、多くの人がこの一見ささいな問題に遭遇し、「Railsの方法」で1時間を無駄に費やしてしまいます。おそらくヘルパーとこれを行う「Railsの方法」はありますか?またはより良いRuby方法?

51
tribalvibes

これは本当にあなたの質問に答えませんが、もっと簡単な方法があります

Rails 5の場合、 helpers プロキシを使用します

helpers.link_to '...', '...'

Rails 3 and 4の場合、コントローラからヘルパーを使用しているため、view_contextを使用できます

# in the controller code
view_context.link_to '...', '...'

# instead of using your mixin code 
link_to '...', '...'

Rails 2の場合、コントローラからヘルパーを使用しているため、実際に@templateメンバー変数にアクセスできますコントローラ、@テンプレートはビューであり、すでにUrlHelperが混在しています

# in the controller code
@template.link_to '...', '...'

# instead of using your mixin code 
link_to '...', '...'

コントローラ以外のコードからurlhelperを使用する必要がある場合、あなたの解決策はおそらく行く方法です

60
house9

Rails 3,4 and 5と互換性があります:

view_context.link_to
114
Yacine Zalouani

あなたはこのようにそれを行うことができます:

ActionController.helpers.link_to("Click Me!", awesome_path)

しかし、実際には、そのリンクを生成するためのより良い場所は、UrlHelperおよびその他のビュー関連のヘルパーが既に含まれているヘルパーモジュールにある可能性があります。

[更新]

このアプローチは古く、機能しなくなりました。

1
brentmc79

ActionController.helper.my_methodを使用して、コントローラーで組み込みヘルパーメソッドを使用する独自のヘルパーメソッドを使用しても問題が発生しました。

各フラッシュに対してrender_to_stringを使用することは明らかに機能しますが、フラッシュごとにそれほど多くの小さなパーシャルを作成したくありません。

私の解決策は、コントローラーがコードをパーシャルで実行するための小さなヘルパーを作成することでした。

コントローラーのヘルパーメソッド:

def h(&block)
  render_to_string(:partial => 'helper', :locals => {:block => block})
end

HAMLパーシャル(helper.html.haml):

= instance_eval &block 

ERB(helper.html.erb)でも同様に機能します。

<%= instance_eval &block %>

ヘルパーで定義されているmy_custom_helper_functionを呼び出すには、コントローラーで次のように使用します。

redirect_to url, :notice => h{my_custom_helper_function}
0