LoginSignup
1
0

More than 5 years have passed since last update.

url_for(@hogeable) をview/controller以外からどうしても使いたいときは

Last updated at Posted at 2018-04-26

url_for(ポリモーフィックなモデルのインスタンス) をやろうとしたときにちょっとハマったので、自分用めも。

前提としては、

  • view/controller以外からurl_forを使いたい
  • でも、 Routing とか UrlHelpers とかはincludeしたくない...

など。2点めがポイント。

[1] pry(main)> Rails.application.routes.url_helpers.url_for(like.likeable)

ActionController::UrlGenerationError: No route matches ・・・(以下略

😨

url_forの定義

UrlHelperの先でRoutingUrlForみたいなモジュールが読まれてて、そこで

actionview/lib/action_view/routing_url_for.rbから抜粋
method = _generate_paths_by_default ? :path : :url
builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.send(method)

case options
when Symbol
  builder.handle_string_call(self, options)
when Class
  builder.handle_class_call(self, options)
else
  builder.handle_model_call(self, options)
end

みたいな感じで定義されてる。

ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder を使ってみる

こいつ だ。中でいろいろ頑張ってくれている、うん。(ちゃんと読んでない :sweat_smile:

ということで、

def path_for(hogeable)
  builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.send(:path)
  builder.handle_model_call(Rails.application.routes.url_helpers, hogeable)
end

def url_for(hogeable)
  builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.send(:url)
  builder.handle_model_call(Rails.application.routes.url_helpers, hogeable)
end

みたいに定義すれば

[1] pry(main)> path_for(like.likeable)
=> "/blogs/1"

キタ━━━━(゚∀゚)━━━━!!

ってなります。

さいごに

確かに、どこからでもurl_for呼ぶことはできた。
でも、たぶん本来こういう使い方しなくてもいいように考えてね、ってのがRailsの思想なんだろうなー・・・

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0