Rails 5.2 Active Storageを試してみた

Rails 5.2 Active Storage を試してみた

職場の発表向けに資料を作ったので、一部変更し公開します。

目次

  • 概要
  • サンプルプログラム
  • CarrierWave との差異
  • まとめ

概要

Rails 5.2 の新機能
https://railsguides.jp/active_storage_overview.html

サンプルプログラム

  • Ruby 2.5.0
  • Rails 2.5.0.rc1
  • 簡易ブログ
  • 画像のアップロード・表示 (minio(s3))

rails new, scaffold

$ rails _5.2.0.rc1_ new active_storage_sample -d mysql -B
$ rails generate scaffold Article title:string content:text

Active Storage の設定

$ rails active_storage:install
マイグレーションファイルが作成される
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]

  def change
    create_table :active_storage_blobs do |t|
      t.string :key,  null: false
      t.string :filename, null: false
      t.string :content_type
      t.text :metadata
      t.bigint :byte_size,  null: false
      t.string :checksum, null: false
      t.datetime :created_at, null: false
      t.index [ :key ], unique: true
    end

    create_table :active_storage_attachments do |t|
      t.string :name, null: false
      t.references :record, null: false, polymorphic: true, index: false
      t.references :blob, null: false
      t.datetime :created_at, null: false
      t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
    end
  end
end

Active Storage S3 の設定

config/storage.yml
local:
  service: Disk
  root: <%= Rails.root.join("storage") %>
  
amazon:
  service: S3
  access_key_id: minio_access_key
  secret_access_key: minio_secret_key
  region: us-east-1
  bucket: <%= "active-storage-sample#{Rails.env}" %>
  endpoint: http://s3:9000
  force_path_style: true
config/environments/development.rb
config.active_storage.service = :amazon

Article に image を追加

app/models/article.rb
class Article < ApplicationRecord
  has_one_attached :image
  validates :title, presence: true
end
app/controllers/articles_controller.rb
def article_params
  params.require(:article).permit(:title, :content, :image)
end
app/views/articles/_form.html.erb
<div class="field">
  <%= form.label :image %>
  <%= form.file_field :image %>
</div>
app/views/articles/show.html.erb
<p>
<strong>Image:</strong>
  <% if @article.image.attached? %>
    <%= image_tag(url_for(@article.image)) %>
    <%= image_tag @article.image.variant(resize: "100x100") %>
  <% end %>
</p>

動作

DB登録内容

article = Article.last
=> #<Article id: 2, title: "aaa", content: "bb\r\ncc", created_at: "2018-03-19 05:44:59", updated_at: "2018-03-19 05:44:59">

article.image
=> #<ActiveStorage::Attached::One:0x00007f5ef8125350
@name="image", @record=#<Article id: 2, title: "aaa", content: "bb\r\ncc", created_at: "2018-03-19 05:44:59", updated_at: "2018-03-19 05:44:59">, @dependent=:purge_later>
article.image.attachment
=> #<ActiveStorage::Attachment id: 7, name: "image",
record_type: "Article", record_id: 2,
blob_id: 7, created_at: "2018-03-19 05:44:59">

article.image.attachment.blob
=> #<ActiveStorage::Blob id: 7, key: "gaKmNyn6kJCNz9JYVdKJVLWH", filename: "ねこ.JPG", content_type: "image/jpeg", metadata: {"identified"=>true, "analyzed"=>true}, byte_size: 5981, checksum: "EGiUJf7A8ksMxFJVVVq8Iw==", created_at: "2018-03-19 05:44:59">
  • rails active_storage:install で作成されたマイグレーションの内容

S3登録内容

$ mc ls s3/active-storage-sampledevelopment
5.8KiB gaKmNyn6kJCNz9JYVdKJVLWH
0B variants/

$ mc ls s3/active-storage-sampledevelopment/variants/
0B gaKmNyn6kJCNz9JYVdKJVLWH/
$ mc ls s3/active-storage-sampledevelopment/variants/gaKmNyn6kJCNz9JYVdKJVLWH/
1.8KiB e10bc39319f71677aea41f1f09fdfb95544fbf6d39158366b99eb1c26ed7733e
  • 指定バケット直下にActiveStorage::Blobのkeyに紐付いたファイルを配置
  • variantsはリサイズした画像(初回アクセス時に生成)

画像表示

それぞれのHTMLは以下のようになる
オリジナル
<%= image_tag(url_for(@article.image)) %>
<img src="/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--f193578158a609a322b9d73018591942cc57a340/%E3%81%AD%E3%81%93.JPG">
オリジナルRailsログ
Started GET "/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--f193578158a609a322b9d73018591942cc57a340/%E3%81%AD%E3%81%93.JPG" for 172.20.0.1 at 2018-04-06 20:20:50 +0900

Redirected to http://s3:9000/active-storage-sampledevelopment/gaKmNyn6kJCNz9JYVdKJVLWH?response-content-disposition=inline%3B%20filename%3D%22%253F%253F.JPG%22%3B%20filename%2A%3DUTF-8%27%27%25E3%2581%25AD%25E3%2581%2593.JPG&response-content-type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minio_access_key%2F20180406%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20180406T112050Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=3568335da347f42b1c423932fd6d6f4d6468a8605cbb833db4454f77104a6cf8
リサイズ
<%= image_tag @article.image.variant(resize: "100x100") %>
<img src="http://localhost:3000/rails/active_storage/variants/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--f193578158a609a322b9d73018591942cc57a340/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCam9MY21WemFYcGxTU0lNTVRBd2VERXdNQVk2QmtWVSIsImV4cCI6bnVsbCwicHVyIjoidmFyaWF0aW9uIn19--32d3627a3c908ea42192535ae07c1abff1db16bb/%E3%81%AD%E3%81%93.JPG">
リサイズRailsログ
Started GET "/rails/active_storage/variants/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--f193578158a609a322b9d73018591942cc57a340/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCam9MY21WemFYcGxTU0lNTVRBd2VERXdNQVk2QmtWVSIsImV4cCI6bnVsbCwicHVyIjoidmFyaWF0aW9uIn19--32d3627a3c908ea42192535ae07c1abff1db16bb/%E3%81%AD%E3%81%93.JPG" for 172.20.0.1 at 2018-04-06 20:20:50 +0900

Redirected to http://s3:9000/active-storage-sampledevelopment/gaKmNyn6kJCNz9JYVdKJVLWH?response-content-disposition=inline%3B%20filename%3D%22%253F%253F.JPG%22%3B%20filename%2A%3DUTF-8%27%27%25E3%2581%25AD%25E3%2581%2593.JPG&response-content-type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minio_access_key%2F20180406%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20180406T112050Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=3568335da347f42b1c423932fd6d6f4d6468a8605cbb833db4454f77104a6cf8
  • ActiveStorage用のコントローラに対して、GET
  • S3のURLに対しリダイレクトし、画像を表示

CarrierWave との差異

  • 保存先のバケットやディレクトリ・ファイル名が指定できない
  • 画像の表示時、ActiveStorage用のコントローラからリダイレクト
  • CloudFrontが使用できない(表示用の設定がない)
  • リサイズのタイミングが異なる
  • Exif情報削除などは作り込みが必要そう
  • 登録でのバリデーションエラー時の一時保存機能がない
など

まとめ

  • CarrierWaveをActiveStorageに置き換えることはできない
  • ActiveStorageを使用する場合、制限などあるため注意
  • 今後の機能追加に期待

コメント

このブログの人気の投稿

AMD環境でKVM PCIパススルー (PT2で)

Rails Devise認証のカスタマイズメモ

Ubuntu 16.04 に Munin(CGI) + Nginx をインストール・設定