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

#はじめに
carrierwaveで画像アップロード機能を実装後、アップロードされた画像はAWSのS3に保存できるようにする方法を解説いたします。
なお、carrierwaveを導入していることを前提に解説しています。
carrierwaveの実装がまだの方は[こちらの記事](https://qiita.com/yusei_boxing/items/8c9c2b5ece2fbadc3327)を参考にしてみてください。
#AWSのIAMユーザーとS3バケットの作成
##IAMユーザーの作成
- まず、awsコンソールにログインし、IAMサービスにアクセスします。
- そして、項目のユーザーから「ユーザーを追加」をクリックします。
![スクリーンショット 2021-08-30 12.45.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/0e96f47d-6255-4b28-f382-08bf6aa3e7f3.png)
- ユーザーの設定を行います。![スクリーンショット 2021-08-30 12.49.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/8e7c3ad2-1efd-f71c-b2a8-a7d3d4fa7aba.png)
![スクリーンショット 2021-08-30 13.07.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/f3ed6c84-6def-0803-e431-0bb1dd708c46.png)
![スクリーンショット 2021-08-30 13.14.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/5fa0434f-64bd-3651-11f9-4e6213bf2a2d.png)
![スクリーンショット 2021-08-30 13.17.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/04686d22-a486-4505-9294-00e2280b251b.png)
これでIAMユーザーの設定は完了です。

##S3バケットの作成
- S3サービスにアクセスします。
- そして、項目のバケットからバケットを作成をクリックします。
![スクリーンショット 2021-08-30 13.32.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/a72d4b24-c664-c364-0a83-da4400b96def.png)
![スクリーンショット 2021-08-30 13.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/9f5ae5c8-8973-b188-5444-551c171f7172.png)
![スクリーンショット 2021-08-30 13.38.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/b3a580c2-9b3a-9eea-ec52-e8478ecdcf3e.png)
![スクリーンショット 2021-08-30 14.10.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/b06fa224-87d9-1585-132e-33164939eb57.png)
- そして、作成したIAMユーザーがS3にアクセスできるようにバケットポリシーを追加します。
- まず、先ほど作成したIAMユーザーの「ARN」をコピーします。
![スクリーンショット 2021-08-30 14.20.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/00c309f7-2386-732c-1d05-0b727eee4682.png)
![スクリーンショット 2021-08-30 14.34.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/c7ec74bd-8525-9601-d291-5d2733087cc5.png)
![スクリーンショット 2021-08-30 14.39.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161581/f0b96bcf-b5e0-b599-a884-17a84f57ddde.png)

```:バケットポリシー
{
    "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にアップロードされるようにしています。

```Ruby: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ファイルを作成し、下記のコードを追記します。

```ruby: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を使って環境変数を管理しよう](https://pikawaka.com/rails/dotenv-rails#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%A8%E3%81%AF%EF%BC%9F)
#最後に
これにて、設定完了です。実際に画像をアップロードしS3に保存されているか確認してみてください。
#参考記事
[【Rails】 CarrierWaveチュートリアル](https://pikawaka.com/rails/carrierwave)