2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Catch allルーティングとActive Storage

Posted at

Active Storageを使おうとしたら、ルーティングが干渉する事態が発生しました。

Catch allルーティングとは

Railsのルーティングはresourcesなどによるリソースフルなものや、get 'path/to/:id'のようなパス形式の指定が一般的ですが、ワイルドカードを使うこともできます(Rails Guide)。

ルーティングの一部に*nameと入れると、スラッシュも含んでマッチしうるものがすべて回収されて、アクションの側ではparams[:name]のように取得することができます。特に、get '*all'のように書いてしまえば、あらゆるURLによるGETリクエストがこのルーティングにマッチするようになります。このような、「あらゆるURLにマッチングするルーティング」を「Catch allルーティング」のように呼ぶこともあります。

Catch allルーティングの問題点

ルーティングは上から順に処理されていくので、Catch allルーティングが途中にあると、それ以降にあるルーティングはなんの意味も持たなくなってしまいます。自分で書いたルーティングでそんなことをする人はいないかと思いますが、ここで問題になってくるのがActive Storage(やAction Mailbox)です。

Active Storageなどが提供するルーティングは、通常の設定ではユーザーが手書きしたものよりあとに来てしまうので、Catch allをユーザーが書いているとActive Storageのルーティングは使われなくなってしまいます。

対処法

対処法としては、いくつか考えられます。

Catch allルーティングに穴を開ける

ルーティングには、constraintsとしてそのルーティングを使う条件を指定することができます。ここで%r{(?!rails/).*}のような指定を行って、rails/以下をルーティングから一括して外す、という方法も考えられます。ただし、アドホック感が否定できないです。

ロード順を変える

Active Storageを先にロードできれば、問題は解決します。以下の設定をconfig/application.rbに書きましょう。

application.rb
config.railties_order = [ActiveStorage::Engine, :main_app, :all]

なお、[:all, :main_app]のような設定を紹介しているものも見かけましたが、これを行うとアプリ全体の動作が大きく変化してしまいます。

2
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?