Madogiwa Blog

主に技術系の学習メモに使っていきます。

Ruby on Rails: ダイレクトルーティング(Direct routes)を使って外部サイトのURLをroutesで管理する

OAuthを利用した外部サイトへの認証時のリダイレクトやLPへの導線等、Webサービス内で外部サイトのURLを扱いたいときにRailsのダイレクトルーティング機能を使うとURLの管理をRoutesに統一できて便利だったのでMEMOしておきます📝

ダイレクトルーティング機能とは?

The direct method allows creation of custom URL helpers. https://guides.rubyonrails.org/5_1_release_notes.html#direct-resolved-routes

Rails 5.1で導入された、Railsのダイレクトルーティングは以下のような形でroutes内で外部サイトのURLをdirectの引数に名前、block引数にURL文字列を渡すことでfoo_urlのようなhelperを定義出来る機能です。

direct(:homepage) { "http://www.rubyonrails.org" }
homepage_url # => "http://www.rubyonrails.org"

以下のPRで導入されているので内部実装が気になる方はこちらから参照してください。

github.com

使い方

基本

普通に使う分には先程記載した以下の通りです。

direct(:homepage) { "http://www.rubyonrails.org" }
homepage_url # => "http://www.rubyonrails.org"

引数で任意のクエリ文字列を付与する

例えばhomepage_url(from: 'top')で実行したときにhttp://www.rubyonrails.org?from='top' のようなURLを生成したいとします。

通常のdirectを使用しないroutesだと以下のような形でかけますが、

foo_path(bar: 'baz')
#=> /foo?bar=baz

directを利用したRoutesの場合はblockが評価された結果がそのまま返却されるようなので、定義した文字列が帰ってしまいます。

direct(:homepage) { "http://www.rubyonrails.org" }
homepage_url(for: 'bar') # => "http://www.rubyonrails.org"

このようなケースでは以下のような形でblock引数を利用して引数で渡されたオプションをクエリ文字列に指定してあげると、

  direct(:homepage) { |options|
    uri = URI.parse("http://www.rubyonrails.org")
    uri.query = options.to_param unless options.empty?
    uri.to_s
  }

以下のようにいい感じの使い心地になります✨

Rails.application.routes.url_helpers.homepage_url(from: "top", to: "bar")
#=> "http://www.rubyonrails.org?from=top&to=bar"

おわりに

知らなかったですが、外部サイト含めてRoutesでまとめて管理出来るdirect便利ですね!!

参考

qiita.com