経緯
Ruby on RailsのActive Storageを使用していて、ファイルアクセス時に独自処理を挟みたくなったことはありませんか?
私はあります。
そんなとき、下記の記事で同じことができそうだったので参考にしていました。
しかし、想定の挙動通りに処理が進まず、苦労しました。
原因としては、Railsのバージョンアップによるものでした。
参考にしていた記事で実施すると、特定のRailsバージョンでは意図通り動作しないため、
Active Storageのファイルアクセス時に独自処理を経由させたいとき
のRailsv6.1.0以降の方法についてまとめました。
参考にした記事に沿って実装してみる
-
app/controllers/active_storage/
配下に、blobs_controller.rb
を作成 - 下記の通りActive Storageのblobs_controller.rbを参考にControllerを実装し、デバッグコードを入れてみます(記事から引用、微修正)
class ActiveStorage::Blobs::RedirectController < ActiveStorage::BaseController
include ActiveStorage::SetBlob
def show
hoge
expires_in ActiveStorage.service_urls_expire_in
redirect_to @blob.url(disposition: params[:disposition])
end
## 独自処理
private
def hoge
puts "hogehogehoge"
end
end
問題
実際に処理を動かしてみましたが、仕込んだhogehogehoge
がログに出力されませんでした。
調べていると、こちらのPRでblobs_controller.rb
周辺のファイル構造と処理の中身に変更が入っていました。
変更点
v6.1.0~
とそれ以前でディレクトリ構成に違いがあるため、Railsバージョンによって、自作するControllerの位置を変更する必要があります。また、blobs_controller.rb
内の処理も変更されています。
Rails version | Path |
---|---|
v6.1.0~ | activestorage/app/controllers/active_storage/blobs/redirect_controller.rb |
~v6.0.6.1 | activestorage/app/controllers/active_storage/blobs_controller.rb |
v6.1.0以降のパスと同じようにパスと中身を修正してControllerを作成したところ(app/controllers/active_storage/blobs/blobs_controller.rb
)、ActiveStorageのファイルアクセス時に独自の処理を経由させることができるようになりました。
class ActiveStorage::Blobs::RedirectController < ActiveStorage::BaseController
include ActiveStorage::SetBlob
def show
hoge
expires_in ActiveStorage.service_urls_expire_in
redirect_to @blob.url(disposition: params[:disposition])
end
## 独自処理
private
def hoge
puts "hogehogehoge"
end
end
補足
本記事を投稿している2024年5月現在、Railsの最新v7.1.3.2
では、controllerの記述で
# frozen_string_literal: true
# Take a signed permanent reference for a blob and turn it into an expiring service URL for download.
#
# WARNING: All Active Storage controllers are publicly accessible by default. The
# generated URLs are hard to guess, but permanent by design. If your files
# require a higher level of protection consider implementing
# {Authenticated Controllers}[https://guides.rubyonrails.org/active_storage_overview.html#authenticated-controllers].
class ActiveStorage::Blobs::RedirectController < ActiveStorage::BaseController
include ActiveStorage::SetBlob
def show
expires_in ActiveStorage.service_urls_expire_in
redirect_to @blob.url(disposition: params[:disposition]), allow_other_host: true
end
end
If your files require a higher level of protection consider implementing {Authenticated Controllers}[https://guides.rubyonrails.org/active_storage_overview.html#authenticated-controllers].
下記リンクを参照するようコメントされています。