10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails 6.0】Active Storageを導入する前に知っておきたかったこと(ACLディレクトリ設定)

Last updated at Posted at 2020-02-24

概要

ファイルアップロード機能を実装する際に、Rails5.2で導入されたActive Storageを使ってみました。
実際に使ってみて困ったことがいくつかあったので、誰かのために役立てばと思いまとめておきます。

環境

  • Rails 6.0.2.1
  • Ruby 2.6.5

結論: 困った点と解決方法

困った点

Active Storage のサービスとして、Amazon S3を利用して、以下の点で困りました。

  1. アップロード時にアクセス権限(S3のACL)をpublic-readに設定できない
  2. ファイルを保存するディレクトリが設定できない
    (正確には、S3にはフォルダという概念は存在しないので、ファイルのキー名につけるprefixがつけられない)

解決方法

以下のパッチで対応しました。
この書き方だと、ファイルごとにアクセス権限を変更したり、ディレクトリを変更したりといった細かい設定はできません。

# lib/active_storage/service/better_s3_service.rb

require 'aws-sdk-s3'
require 'active_storage/service/s3_service'
require 'active_support/core_ext/numeric/bytes'

module ActiveStorage
  class Service::BetterS3Service < Service::S3Service
    attr_reader :root

    def initialize(bucket:, upload: {}, root:, **options)
      @root = root
      super(bucket: bucket, upload: upload, **options)
    end

    def upload(key, io, checksum: nil, content_type: nil, **)
      instrument :upload, key: key, checksum: checksum do
        object_for(key).put(upload_options.merge(body: io, content_md5: checksum, content_type: content_type, acl: 'public-read'))
      rescue Aws::S3::Errors::BadDigest
        raise ActiveStorage::IntegrityError
      end
    end

    private
      def object_for(key)
        path = root.present? ? File.join(root, key) : key
        bucket.object(path)
      end
  end
end

以下のようにrootを設定する。

# config/storage.yml
amazon:
  service: BetterS3
  root: root-directory

1. アップロード時にアクセス権限(S3のACL)

アップロードしたファイルにパブリック読み取りアクセス許可をつけようとしましたが、v6.0.2.1ではアップロード時に権限を設定することはできません。

ただ2019年7月のPR1で、publicというオプションをstorage.ymlで設定できる変更がマージされたので、将来的にはサポートされそうです。

いくつかの記事2やissueへのコメント3を参考にしてパッチをあてる形で対応しました。

2. ファイルを保存するディレクトリが設定できない

S3にアップロードするファイルにprefixをつけて、フォルダを作成したいことは多々あると思いますが、現時点(v6.0.2.1)のActive Storageではサポートされていません。
「Active Storageでフォルダーを使う」といった旨のissue4 で議論されていますが、あまり議論が進んでいないので、まだまだサポートされなそうですね…。

こちらも先述のissue4にあったパッチ5を利用して、config/storage.ymlから特定のディレクトリ名を設定できるようにしました。

まとめ

Active Storageを使ってみましたが、意外とサポートされていない機能が多く、少し驚きました。
Delyさんの記事にもありましたが、Rails本体に入っていても過信せず、使う前にユースケースを満たしているか利用すべきだと勉強になりました。

読んでいただきありがとうございました!

  1. Permanent URLs for Active Storage blobs by peterzhu2118 · Pull Request #36729 · rails/rails · GitHub

  2. Rails の ActiveStorage を S3 で使ったらPublicなURLが取れなかった - Qiita

  3. ActiveStorage: Allow access to backing file from Service API · Issue #31419 · rails/rails · GitHub

  4. Folder with active storage · Issue #32790 · rails/rails · GitHub 2

  5. (Folder with active storage · Issue #32790 · rails/rails · GitHub)

10
5
1

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
10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?