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

Rails7のActiveStorageでファイルのURL(key)を変更する方法

Last updated at Posted at 2023-08-05

株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。

DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら弊社HPからご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。

  • プロジェクトでRailsエンジニアが足りなくて困っている
  • Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
  • オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい

また、Railsエンジニアも募集しておりますので、興味がありましたら弊社HPからご連絡いただけますと幸いです。

前提

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_blobskeyという項目で管理しています。

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

以上です。

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