株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。
ActiveStorage経由でアップロードしたファイルを表示する際に、そのファイルのURLはランダムに生成されます。
そのURLを変更したい時があり、その方法がなかなか見つからなかったのでメモとして残しておきます。
2種類のやり方が見つかったので、状況に応じて使い分けていただくといいかと思います。
前提
Ruby:v3.2.0
Ruby on Rails:v7.0.5
ActiveStorageを利用する各モデルでメソッドを定義する方法
app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
# すべてのモデルに継承される。
# create_blobメソッドを利用するモデルの中でオーバーライドをしないとエラーになる。
def attachable_storage_path
raise NotImplementedError
end
# すべてのモデルに継承される。
# ActiveStorageを利用するモデルの中で、create_blobメソッドを利用してアタッチする。
def create_blob(attachable)
return if attachable.nil?
ActiveStorage::Blob.new.tap do |blob|
blob.filename = attachable.original_filename
blob.key = attachable_storage_path
blob.upload(attachable)
blob.save!
end
end
end
app/models/application_record.rb
class Content < ApplicationRecord
has_one_attached :image
# ActiveStorageのkeyを変更する際には、このメソッドを利用する。
def image_attach(attachable)
return false unless self.persisted?
image.attach(create_blob(attachable))
end
# ApplicationRecordにあるメソッドをオーバーライド。
def attachable_storage_path
"<key生成の処理>" #ここにkeyの生成を指定する。他のActiveStorageのレコードのkeyと被らないように生成しないとエラーになる。
end
end
Railsアプリケーション生成時に変更する方法
ActiveStorageでは、アップロードしたファイルのURLはactive_storage_blobs
のkey
という項目で管理しています。
ActiveStorageの中身のソースコードを見ていくと、key
の生成のソースコードは以下のようになっていました。
ActiveStorageのGitHubのソースコード
上記を抜粋したものは以下のようになっています。
rails/activestorage/app/models/active_storage
class ActiveStorage::Blob < ActiveStorage::Record
# ...省略...
def key
# We can't wait until the record is first saved to have a key for it
self[:key] ||= self.class.generate_unique_secure_token(length: MINIMUM_TOKEN_LENGTH)
end
# ...省略...
end
上記のように作成されているkey
の生成をオーバーライドして、こちら側で利用したいkey
の形で生成することができます。
今回はファイル名にしたかったので、以下のようにしました。
config/application.rb
module App
class Application < Rails::Application
# 以下を追加
Rails.application.config.to_prepare do
class ActiveStorage::Blob
def key
self[:key] ||= "<key生成の処理>" #ここにkeyの生成を指定する。他のActiveStorageのレコードのkeyと被らないように生成しないとエラーになる。
end
end
end
end
end
以上です。