LoginSignup
40
39

More than 3 years have passed since last update.

Rails6.0のActive Storageに関する変更点まとめ

Last updated at Posted at 2019-06-18

Rails5.2から登場したActive Storageですが、Rails6.0になっていくつかの変更があったのでまとめました。

1. 画像形式のBMPtiffpjepgをサポート

Active Storageがサポートする画像形式に、以下の3つが追加されました。

1-1. BMP

Windows端末で標準的な画像の保存形式です。画像を点の集まりとして記録しています。
拡張子は.bmpです。

1-2. tiff

Tagged Image File Formatの略で、ビットマップ画像の符号化形式の一つです。 タグと呼ばれる識別子を使うことによって、様々な形式のビットマップ画像を柔軟に表現できます。
拡張子は.tifまたは.tiffです。

1-3. progressive JPEG

まずイメージ全体を荒い低解像度で表示し、徐々に細かい高解像度で表示していく方式のJPEGです。
拡張子は.jpgまたは.jpegです。

2. Active Storageが生成するroutesのprefixが指定可能に

Rails5.2までは、Active Storageが生成するroutesのprefixは/rails/active_storageで固定でしたが、Rails6.0では任意のprefixが設定できるようになりました。

2-1. デフォルトの場合

$ bundle exec rails routes -c active_storage
                   Prefix Verb URI Pattern                                                                              Controller#Action
       rails_service_blob GET  /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
rails_blob_representation GET  /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
       rails_disk_service GET  /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
update_rails_disk_service PUT  /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
     rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create

2-2. prefixに/filesを指定した場合

/config/application.rb
module RailsApp
  class Application < Rails::Application
...
    config.active_storage.routes_prefix = '/files'
  end
end
$ bundle exec rails routes -c active_storage
                   Prefix Verb URI Pattern                                                               Controller#Action
       rails_service_blob GET  /files/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
rails_blob_representation GET  /files/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
       rails_disk_service GET  /files/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
update_rails_disk_service PUT  /files/disk/:encoded_token(.:format)                                      active_storage/disk#update
     rails_direct_uploads POST /files/direct_uploads(.:format)                                           active_storage/direct_uploads#create

3. アップロードしたファイルがストレージに保存されるタイミングがsave時に変更

Rails5.2までは、インスタンスのattributeに代入した時点で、アップロードしたファイルがストレージに保存されていました。
Rails6.0では、saveしたタイミングでストレージに保存されるよう変更になっています。saveトランザクションがコミットされた後に、ストレージに保存されます。

3-1. Rails5.2まではインスタンスのattributeに代入したタイミング

@user.avatar = params[:avatar]

3-2. Rails6.0ではsaveしたタイミング

@user.save!

4. ActiveStorage::Reflectionモジュールが追加

新たに追加されたActiveStorage::Reflectionモジュールのreflect_on_all_attachmentsreflect_on_attachmentといったメソッドを使うことで、定義されたattachmentsの情報を取得することができます。

app/models/user.rb
class User < ApplicationRecord
  has_one_attached :avatar
  has_many_attached :highlights
end

このようなUserモデルがあった場合、ActiveStorage::Reflection#reflect_on_attachmentメソッドとActiveStorage::Reflection#reflect_on_all_attachmentsメソッドを使うと、それぞれ以下のような挙動になります。

4-1. ActiveStorage::Reflection#reflect_on_attachment

reflection = User.reflect_on_attachment(:avatar)
# => #<ActiveStorage::Reflection::HasOneAttachedReflection:0x00007f9e26c37460 @name=:avatar, @scope=nil, @options={:dependent=>:purge_later}, @active_record=User (call 'User.connection' to establish a connection), @klass=nil, @plural_name="avatars">
reflection.name
# => :avatar
reflection.macro
# => :has_one_attached

4-2. ActiveStorage::Reflection#reflect_on_all_attachments

reflections = User.reflect_on_all_attachments
=> [#<ActiveStorage::Reflection::HasOneAttachedReflection:0x00007fbedcaf9608 @name=:avatar, @scope=nil, @options={:dependent=>:purge_later}, @active_record=User (call 'User.connection' to establish a connection), @klass=nil, @plural_name="avatars">, #<ActiveStorage::Reflection::HasManyAttachedReflection:0x00007fbedcab50c0 @name=:highlights, @scope=nil, @options={:dependent=>:purge_later}, @active_record=User (call 'User.connection' to establish a connection), @klass=nil, @plural_name="highlights">]
reflections[0]
=> #<ActiveStorage::Reflection::HasOneAttachedReflection:0x00007f9e26c37460 @name=:avatar, @scope=nil, @options={:dependent=>:purge_later}, @active_record=User (call 'User.connection' to establish a connection), @klass=nil, @plural_name="avatars">
reflections[0].name
=> :avatar
reflections[0].macro
=> :has_one_attached
reflections[1]
=> #<ActiveStorage::Reflection::HasManyAttachedReflection:0x00007fbedcab50c0 @name=:highlights, @scope=nil, @options={:dependent=>:purge_later}, @active_record=User (call 'User.connection' to establish a connection), @klass=nil, @plural_name="highlights">
reflections[1].name
=> :highlights
reflections[1].macro
=> :has_many_attached

5. ActiveStorage::Blob#openメソッドが追加、ActiveStorage::Downloadingモジュールが非推奨

ActiveStorage::Blob#openというメソッドが追加されました。
blobをアップロード後に、何かしら処理を加えたい場合に使います。
blobをtmpファイルとして保持しており、ウイルススキャンやメディアトランスコーダによる変換など、外部プログラムを使った処理を実行することもできます。

message.video.open do |file|
  system '/path/to/virus/scanner', file.path
  # ...
end

また、元々このような形で使う想定で用意されていたActiveStorage::Downloadingモジュールが非推奨になっています。

6. Google Cloud Storageのストリーミングダウンロードをサポート

google-cloud-storage gemのバージョンが、1.8以上から1.11以上に引き上げられました。
これにより、ストリーミングダウンロードに対応するようになりました。

7. image_processing gemの導入

ファイルを変換するためのgemが、mini_magickからimage_processingに変更されました。
image_processingmini_magickruby-vipsのwrapperで、画像のリサイズや加工を行います。

Rails 6.0.0.rc1では、Gemfileにおいてデフォルトでコメントアウトされています。

Gemfile
# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

コメントアウトを外して、bundle installしましょう。

8. 既存の画像を置き換え

アタッチされたモデルをupdateまたはupdate!で更新すると、新たに画像を追加するのではなく既存の画像を置き換えます。

@user.update!(images: [  ])
40
39
6

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
40
39