転職活動用にポートフォリオを作っています。
DTPの作品も多く、画像が全部でおよそ18MBあったのですが、Herokuの無料版の容量は5MBのため、画像の外部ストレージとしてS3を利用するようにしました。
調べたら、多くの人がつまづいているようでしたので、自分のためにも手順をメモしておこうと思います。
S3の利用設定
まずは、S3の利用設定を行います。手順については、こちらのサイトを大変参考にさせていただきました。
[【Rails】S3へ『CarrierWave+fog』を使って画像アップロードする方法][1]
[1]:http://vdeep.net/rubyonrails-carrierwave-s3
↑こちらの記事以上に丁寧な説明はないと思いますので、S3の設定についてはこちらをご参照いただければ幸いです。
gemをインストール
画像アップロードに必要な、以下のgemをインストールします。
-
carrierwave
…画像をアップロードするgem -
mini_magick
…画像をリサイズするgem -
fog
…S3などのクラウドストレージ内の画像を参照するgem
それぞれ、設定の書き方は以下の通り。
group :production do
gem 'pg', '0.18.0'
gem 'rails_12factor', '0.0.2'
gem 'fog-aws'
end
gem 'carrierwave'
gem 'mini_magick'
忘れずにbundle install
します。
なお、私の場合ですがfog
というgemではaws関連のdependencyのgemがインストールされず、fog-aws
を利用しないと先に進めませんでした。
アップローダーの生成
CarrierWaveをインストールすると、画像のアップローダーの生成ができるようになりますので、以下のコマンドで生成します。
$ rails generate uploader カラム名
最後の「カラム名」は、画像を必要とするモデルのデータベースのカラム名です。単数形、頭文字大文字で表記します。私は、すでにあったテーブルのカラム名から、Image
にしました。
なお、画像のファイル名が文字列のため、imageカラムのデータ型はstring型です。
$ rails generate uploader Image
create app/uploaders/image_uploader.rb ←生成
CarrierWaveに、imageカラムがuploaderと関連していることを認識させるためには、mount_uploader
というメソッドを使います。(今回モデル名はwork
)
class Work < ApplicationRecord
mount_uploader :image, ImageUploader
end
# viewファイルの書き換え
そして、今度はビューファイルをいくつか変更します。まずは、ファイルをアップロードする機能をviewに持たせます。画像をアップロードするフォームのタグをfile_field
にしました。
= f.label :image, "画像:"
= f.file_field :image
そして、workの一覧ページの書き方も、CarrierWaveに合わせて書き換えます。
-# 書き換え前
- @works.each do |work|
= image_tag work.image
-# 書き換え後
- @works.each do |work|
= image_tag work.image.url
work.imageの後にurlをつけるのがポイントです。
以上の動作により、無事画像のアップロードができました。
本番環境で画像のアップロード先を変える
この時、画像ファイルはデフォルトでは、ローカルのフォルダにアップロードさせています。
storage :file
storage :file
という記述は、ローカルのファイルシステムに画像を保存するための記述です。
これだと、Herokuにデプロイした時に容量を圧迫してしまうので、本番環境だけS3に画像をアップするようにしたいと思います。
if Rails.env.production?
storage :fog
else
storage :file
end
if Rails.env.production?
で本番環境ではクラウドストレージに保存するようにしています。
さらに、同じく、image_uploaderに下記のように記載します。
if Rails.env.production?
CarrierWave.configure do |config|
config.fog_credentials = {
# Amazon S3用の設定
:provider => 'AWS',
:region => ENV['S3_REGION'], # S3に設定したリージョン。
:aws_access_key_id => ENV['S3_ACCESS_KEY'],
:aws_secret_access_key => ENV['S3_SECRET_KEY']
}
config.fog_directory = ENV['S3_BUCKET']
end
それぞれ、以下のように設定します。ちなみに、東京のリージョンはap-northeast-1
です。
$ heroku config:set S3_ACCESS_KEY="S3のAccessキーを入力"
$ heroku config:set S3_SECRET_KEY="同様に、Secretキーを入力"
$ heroku config:set S3_BUCKET="Bucketの名前を入力"
$ heroku config:set S3_REGION="Regionの名前を入力"
ここまで書いたらようやく本番環境にデプロイです。デプロイして動作を試します。
・・・できた!!!無事アップロード完了です!!
追伸:エラーへの対処
なお、本番環境ではすぐに順調に動作をしたわけではなく、私の場合はAccess Denied
というエラーに遭いました。