LoginSignup
0
0

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

Last updated at Posted at 2023-08-05

株式会社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_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