株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。
DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら弊社HPからご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい
また、Railsエンジニアも募集しておりますので、興味がありましたら弊社HPからご連絡いただけますと幸いです。
前提
ActiveStorage経由でアップロードしたファイルを表示する際に、そのファイルのURLはランダムに生成されます。
そのURLを変更したい時があり、その方法がなかなか見つからなかったのでメモとして残しておきます。
2種類のやり方が見つかったので、状況に応じて使い分けていただくといいかと思います。
開発環境は以下の通りです。
Ruby:v3.2.0
Ruby on Rails:v7.0.5
ActiveStorageを利用する各モデルでメソッドを定義する方法
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
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のソースコード
上記を抜粋したものは以下のようになっています。
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
の形で生成することができます。
今回はファイル名にしたかったので、以下のようにしました。
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
以上です。