carrierwaveを利用してawsのs3に画像をアップロードできるようにし、画像未アップロード時にはデフォルト画像を表示させる方法


はじめに

carrierwaveで画像アップロード機能を実装後、アップロードされた画像はAWSのS3に保存できるようにする方法を解説いたします。
なお、carrierwaveを導入していることを前提に解説しています。
carrierwaveの実装がまだの方はこちらの記事を参考にしてみてください。

AWSのIAMユーザーとS3バケットの作成

IAMユーザーの作成

  • まず、awsコンソールにログインし、IAMサービスにアクセスします。
  • そして、項目のユーザーから「ユーザーを追加」をクリックします。
  • ユーザーの設定を行います。 これでIAMユーザーの設定は完了です。

S3バケットの作成

  • S3サービスにアクセスします。
  • そして、項目のバケットからバケットを作成をクリックします。
  • そして、作成したIAMユーザーがS3にアクセスできるようにバケットポリシーを追加します。
  • まず、先ほど作成したIAMユーザーの「ARN」をコピーします。
バケットポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt000001",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::ARNをここに貼り付ける"
            },
            "Action": "s3*",
            "Resource": "arn:aws:s3:::バケット名"
        }
    ]
}

これでAWSの設定は完了です。

uploaderクラスの設定

作成したuploaderクラスの設定(私の場合はImageUploaderクラス)を下記の通り追記します。
開発環境、テスト環境では「strage: file」、本番環境では「strage: fog」を指定することにより、本番環境のみ画像がS3にアップロードされるようにしています。

app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick
  include CarrierWave::MiniMagick

  # only pg,jpeg,gif,png
  def extension_white_list
    %w(jpg jpeg gif png)
  end

  if Rails.env.development?
    storage :file
  elsif Rails.env.test?
    storage :file
  else
    storage :fog
  end

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

#注) if original_filename.present?を記載しないと、画像をアップロードしていない場合でもファイル名を作成してしまい、実在しない画像を参照してしまいます。
  def filename
    if original_filename.present?
      time = Time.now
      name = time.strftime('%Y%m%d%H%M%S') + '.jpg'
      name.downcase
    end
  end

次に、config/initializers/の下にcarrierwave.rbファイルを作成し、下記のコードを追記します。

config/initializers/carrierwave.rb
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'

#本番環境以外ではS3を参照しないように設定しています。
unless Rails.env.development? || Rails.env.test?
  CarrierWave.configure do |config|
    config.storage :fog
    config.fog_provider = 'fog/aws'
    config.fog_directory  = 'バケット名'
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: アクセスキーID',
      aws_secret_access_key: 'シークレットアクセスキー',
      region: 'ap-northeast-1',
      path_style: true
    }
  end 
end

アクセスキーIDとシークレットアクセスキーは悪用される可能性があるため、実装する際は環境変数を利用することをお勧めします。
今回は環境変数の設定については省略します。

環境変数についての参考記事:【Rails】 dotenv-railsを使って環境変数を管理しよう

最後に

これにて、設定完了です。実際に画像をアップロードしS3に保存されているか確認してみてください。

参考記事

【Rails】 CarrierWaveチュートリアル