↪️

ドメイン名変更時のリダイレクトを Rails のルーティングで設定する

2022/09/02に公開

結論

Ruby on Rails アプリケーションで old.example.net へアクセスがあった場合に、パスを維持したまま new.example.com へ 301 リダイレクトしたければ、routes.rb の先頭に以下を追加すればよい。

config/routes.rb
constraints host: 'old.example.net' do
  get '/(*path)', to: redirect { |path_params,| "https://new.example.com/#{path_params[:path]}" }
end

背景

Heroku の無料プランで個人開発 Rails アプリを herokuapp.com のドメインを利用して動かしている。Heroku 無料プラン廃止のリリース を受け、将来スムーズに別のインフラへ移せるよう、カスタムドメインへ移行することにした。

自分でコントロールできるのであれば、移行前 URL から移行先 URL へのリダイレクトはアプリケーションよりも前段で行いたいところである。しかし、https://reinteractive.com/posts/504-how-to-redirect-a-rails-application-to-a-new-domain-name より、

カスタムドメインを設定しても、アプリの Heroku ドメインは常にアクティブなまま維持されます。ユーザーがカスタムドメインのみ使用するようにする場合は、アプリから HTTP ステータスコード 301 Moved Permanently を送信して、Web ブラウザにカスタムドメインの使用を指示する必要があります。

とのことなので、Heroku ではアプリケーションでリダイレクトする必要があった。

検討

ググった結果、Rails ガイドの「Rails のルーティング」と合わせて以下の記事を参考にした。
なぜ get '*path'redirect('https://new.example.com/%{path}') といった書き方ができないかはこちらを参照してほしい。
https://reinteractive.com/posts/504-how-to-redirect-a-rails-application-to-a-new-domain-name

他に、rack-rewrite gem を使う方法も数多く紹介されていた。より前段の Rack で処理する方がオーバーヘッドを減らせるので、トラフィックの多いアプリケーションなどではこちらの方法がよいだろう。しかし、依存が増える点、かつ、処理が追いにくく記述も複雑になる点から、シンプルな routes.rb に書く方法を採用することにした。

ApplicationControllerbefore_action フィルタで処理する方法も見かけたが、routes.rb で処理した方がシンプルかつオーバーヘッドも少ない。


ちなみに、裏SF創作講座というサービスで実際にこのコードを使用している。
https://github.com/fuji-nakahara/genron-sf-fun/blob/fb37fe75938afec4a7e2aec45cebf74253da553c/config/routes.rb#L4-L6

GitHubで編集を提案

Discussion