すでにメンバーの場合は

無料会員登録

GitHubアカウントで登録 Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

登録がまだの方はこちらから

Pikawakaにログイン

GitHubアカウントでログイン Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

Rails

【Rails】Active Storageを使って画像をアップしよう!

ぴっかちゃん
ぴっかちゃん

Active Storageとは、ファイルアップロードを簡単に実装できるgemです。railsの標準のgemで、rails5.2から追加されました。

Active Storageの使い方

この章では、Active Storageの使い方について解説します。

Active Storageの導入

Active Storageを使うには以下のコマンドを実行します。

ターミナル
1
2
$ rails active_storage:install
$ rails db:migrate

最初のコマンドを実行するとactive_storage_blobs とactive_storage_attachmentsという2つのテーブルを作成するマイグレーションファイルが生成されます。
active_storage_blobsは実際にアップロードしたファイルが保存されるテーブルで、active_storage_attachmentsは中間テーブルになります。

次にモデルに対してActive Storage用の設定を追加します。

1つのファイルを追加する

モデル
1
has_one_attached :カラム名

上のように記述すると1つのファイルを選択します。

複数のファイルを追加する

複数のファイルをアップロードしたい場合は下記のように記述します。

モデル
1
has_many_attached :カラム名

保存するカラム名の命名方

userモデルに「image」というカラムで保存したい場合はmodelsフォルダ内のuser.rbにこのように記述します。

app/models/user.rb
1
has_one_attached :image

ここでのポイントはわざわざusersテーブルにカラムを追加する必要がないということです。
これは非常に便利ですよね!
この場合コントローラーでストロングパラメーターを定義する際はuserモデルに追加すればOKです。

画像の投稿フォームの作成方法はform_withの記事、またはform_forの記事を参照してください。

表示の仕方

上のように定義した場合、保存したファイルを表示させるには下記のように記述します。
画像なのでimage_tagを使用しましょう。

ビューファイル
1
<%= image_tag user.image %>

削除の仕方

画像を削除するにはpurgeメソッドを使います。

コントローラー | 画像の削除
1
2
user = User.find(params[:id])
user.image.purge

画像の大きさを調整しよう

今のままだと表示される画像はもとのファイルの大きさのままです。
そのためにImageMagickという画像変換ツールをインストールします。
ターミナルで下記のコマンドを実行し、ImageMagickをインストールします。

ターミナル | ImageMagickの導入
1
$ brew install imagemagick

次にImageMagickをrailsで使えるようにするためmini_magickというgemをインストールします。
Gemfileに下記のコードを追記し、bundle installコマンドを実行してください。

Gemfile | mini_magickの追加
1
gem 'mini_magick'

これで準備はOKです。

画像の幅を統一したい場合はvariantメソッドを使用します。

ビューファイル
1
<%= image_tag user.image.variant(resize:'200x200') %>

上のように記述すると200x200のサイズで画像が表示されます。

ファイルの保存先の変更の仕方

ファイルの保存先は開発環境だとconfig/environments/development.rbに書かれています。

config/environments/development.rb
1
config.active_storage.service = :local

デフォルトでは上記のように保存先はローカルに設定されています。
この「local」の部分はどこで定義されているかというとconfig/storage.ymlというファイルに書かれています。

config/storage.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
# amazon:
#   service: S3
#   access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
#   secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
#   region: us-east-1
#   bucket: your_own_bucket

# Remember not to checkin your GCS keyfile to a repository
# google:
#   service: GCS
#   project: your_project
#   credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
#   bucket: your_own_bucket

# Use rails credentials:edit to set the Azure Storage secret(as azure_storage:storage_access_key)
# microsoft:
#   service: AzureStorage
#   storage_account_name: your_account_name
#   storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
#   container: your_container_name

# mirror:
#   service: Mirror
#   primary: local
#   mirrors: [ amazon, google, microsoft ]

これをみるとlocalの時は使用するサービスがDisk、つまりローカルのディスクになっています。
Active Storageではローカルの他にも様々なサービスを指定することができます。
コメントアウトされている部分をみるとAWSのS3、googleのGCS、microsoftのAzureStorageも使うことができます。
使う場合はこちらのコメントアウトを外し、Gemfileに対応したgemを追加する必要があります。

サービス名 使用するgem
AWS aws-sdk-s3
google google-cloud-storage
microsoft azure-storage
Gemfile
1
2
# 例 Gemfileに追記
gem 'aws-sdk-s3'

S3に画像を保存させる

herokuでActive Storgeを使用する場合、サーバーのデータベースに直接保存をしているとherokuの仕様上保存されても24時間経つかインスタンスが再起動されると消えてしまうので、S3などの外部サービスを使う必要があります。
ですので実際にAWSのS3というサービスを使って画像を保存させる設定をしてみましょう。
S3は基本的に、ファイルをアップロードし、そのURLを取得できるAWSのストレージサービスです。
まずはactive strageをS3に対応させるため、各種ファイルの編集を行います。

1. config/storage.ymlの編集

config/storage.yml
1
2
3
4
5
6
amazon:
  service: S3
  access_key_id: <%= ENV['ACCESS_KEY_ID'] %>
  secret_access_key: <%= ENV['SECRET_ACCESS_KEY'] %>
  region: リージョンコードの指定
  bucket: バケット名

amazonの行をコメントアウトを外し、コードを反映させるようにします。
access_key_idとsecret_access_keyは環境変数で指定します。

regionは下記のページで確認をします。
https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html

bucketは自分で作成したバケット名を指定しましょう。
どちらもクオテーションで囲う必要はありません。

2. 環境変数を設定しよう

ターミナルで下記のコマンドを実行します。

ターミナル
1
2
3
$ echo export ACCESS_KEY_ID="CSVに記載されているaccess_key_idカラムの値" >> ~/.bash_profile
$ echo export SECRET_ACCESS_KEY="CSVに記載されているsecret_access_keyカラムの値" >> ~/.bash_profile
$ source ~/.bash_profile

herokuにアプリをデプロイする場合は下記のコマンドでherokuのサーバーに環境変数を設定できます。

ターミナル
1
2
$ heroku config:set ACCESS_KEY_ID="CSVに記載されているaccess_key_idカラムの値"
$ heroku config:set SECRET_ACCESS_KEY="CSVに記載されているsecret_access_keyカラムの値"

3. 開発環境でS3を使えるようにする

config/environments/development.rbを編集し、開発環境でS3が使えるよう変更をします。
31行目のコードを「local」から「amazon」に変更します。

config/environments/development.rb
1
config.active_storage.service = :amazon

4. 本番環境でS3を使えるようにする

config/environments/production.rbを編集し、本番環境でS3が使えるよう変更をします。
42行目のコードを「local」から「amazon」に変更します。

config/environments/production.rb
1
config.active_storage.service = :amazon

5. aws-sdk-s3というgemの追加

Gemfileに下記のコードを追記し、bundle installをします。

Gemfile
1
gem 'aws-sdk-s3'

これでS3の登録がしっかりとできていれば画像はS3にアップロードされます。

この記事のまとめ

  • Active Storageは、ファイルアップロードを簡単に実装できるgemのこと
  • ローカルだけでなく、外部サービスも設定すること出来る

9

わかった!