config/routes.rb
の末尾に *path
などのルーティングがあると、
ActiveStorageのファイルを示すエンドポイント(/rails/active_storage/...
)1よりも先にマッチしてしまう。
config/routes.rb
Rails.application.routes.draw do
...
get "*path" , to: redirect('/')
end
これを回避するためには以下のようにする。
config/routes.rb
Rails.application.routes.draw do
...
get '*path' , to: redirect('/'), constraints: lambda { |req|
req.path.exclude? 'rails/active_storage'
}
end
これで rails/active_storage
を含むパスがマッチしないように設定できる。
constraints
オプションについて
特定のルーティングに制約(constraints)を与えるためのオプションという解釈。
以下のようにして使う。
# match `/users/A12345`, but not `/users/893`
get 'users/:id', to: 'users#show', constraints: { id: /[A-Z]\d{5}/ }
# match port 3000 only
get :users, to: 'users#index', constraints: { port: '3000' }
上述のようにlambdaを指定することもできる。2
get "hi", to: redirect("/foo"), constraints: ->(req) { true }
参考
- https://qiita.com/NaokiIshimura/items/0f0e56c159c95b59b11f
- https://github.com/rails/rails/issues/31228#issuecomment-352900551
- https://y-yagi.tumblr.com/post/92386974040/rails-routing-constraintsについて
- https://railsguides.jp/routing.html#セグメントを制限する
-
定義はこちら https://github.com/rails/rails/blob/v5.2.4.4/activestorage/config/routes.rb#L4 ↩
-
厳密には
request
を引数に取るcall
メソッドが呼び出し可能なオブジェクトを指定すればよさそう。リクエスト毎に呼ばれるcall
がtrueを返す場合にのみ、対象のルーティングがマッチするといった動作のよう。本投稿では触れていないがmatches?
でも可。 ( テストコード 、 実装部分 を参照) ↩