【Rails6】CarrierWaveを使用して、プロフィール画像を設定（導入〜デフォルト画像設定）

## はじめに

CarrierWaveを使用して、プロフィール画像を設定した際躓いたので、備忘録として残します。

## 前提
- マイページは作成済み
- Userモデルにprofile_imageカラムは追加済み
- ログイン機能（アカウント登録等）はdeviseで実装
（スタイル調整は含まれていません。）

## 環境開発

Mac
Ruby 2.7.2
Rails 6.1.3.2
carrierwave　2.0

## 完成イメージ
![スクリーンショット 2021-05-24 15.39.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/b491ba68-015e-cfdb-2fec-273851ba22ab.png)


## 手順
### 1.CarrierWaveを導入

- Gemfileにgemを追記

```
gem 'carrierwave', '~> 2.0'
```
>バージョン2.0以降、CarrierWaveにはRails5.0以降とRuby2.2以降が必要です。Rails 4を使用している場合は、1.xを使用する必要があります。

- ターミナルからインストールする

```
$ bundle install
```
- サーバーの再起動をおこなう

```
$ rails c
```

### 2.CarrierWaveのアップローダーを作成
- `app/uploaders/image_uploader.rb`ファイルを作成

```
$ rails g uploader image
```

### 3.実装したいクラス（今回はUser）に以下のコードを追加

```app/models/user.rb
mount_uploader :profile_image, ImageUploader
```
これにより、Userモデルのprofile_imageカラムと、先ほど作成したアップローダーImageUploaderと紐付けができる。

### 4.Strong Parameterにprofile_imageカラムを追加

```application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :profile_image])
  end
end

```
これを追加していないと、profile_imageのデータを取得できないので、注意！

### 5.アカウント登録画面に、ファイル選択ボックスを追加

```registrations/new.html.erb
  <div class="form-group">
    <%= f.label :profile_image %><br/>
    <%= f.file_field :profile_image %>
  </div>
```
下記のようにアカウント登録時に、「ファイルを選択」を表示できる
![スクリーンショット 2021-05-22 14.14.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/54fdbc40-35cf-40a6-af52-8e64999033f2.png)

### 6.Viewの設定

```app/views/users/show.html.erb
<p>MyPage <%= @user.name %></p>
<% if @user.profile_image? %>
 <%= image_tag @user.profile_image.url %>
<% end %>
```

現状は、こんな感じで表示されます。
![スクリーンショット 2021-05-22 14.19.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/72c01744-9a43-8bd0-8c71-53bbd894ac2f.png)

### 7.日本語訳を変更（devise使用している場合のみ！）
- アカウント登録時に、「Profile image」となっている為、日本語訳へ変更する

- `config/locales/devise.views.ja.yml`に追加する
![スクリーンショット 2021-05-22 20.23.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/0efd999c-9aec-eeaf-84df-96004156a364.png)

※作成していない場合は、ターミナルで下記のコマンドを実施して、追加して下さい。

```
$ rails g devise:i18n:locale ja
```
サーバー起動すると下記のように日本語訳になっています！
![スクリーンショット 2021-05-22 20.19.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/95194b4b-9682-8e4d-34a0-0d2d058a143e.png)

### 8.アカウント登録画面に、ファイル選択ボックスを追加

```registrations/edit.html.erb
  <div class="form-group">
    <%= f.label :profile_image %><br/>
    <%= f.file_field :profile_image %>
  </div>
```
### 9.Strong Parameterにprofile_imageカラムを追加

```application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    # アカウント登録時に許可
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :profile_image])
    # アカウント編集時に許可
    devise_parameter_sanitizer.permit(:account_update, keys: [:name, :profile_image])
  end
end
```
### 10.アカウント編集画面で、現在選択しているプロフィール画像を表示

```registrations/edit.html.erb
  <div class="form-group">
    <%= f.label :profile_image %><br/>
     # ココを追加↓
    <%= image_tag @user.profile_image.url if @user.profile_image? %>
    <%= f.file_field :profile_image %>
  </div>
```
これで、アカウント編集画面で表示されます。
![スクリーンショット 2021-05-22 21.53.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/7bcf9e39-91af-ab30-ad1a-f5691c5f18b2.png)

### 11.画像登録していなユーザーは、デフォルトで画像を表示する

- `app/uploaders/image_uploader.rb`の設定

```app/uploaders/image_uploader.rb
  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  # ↓ココをコメントアウトする
  def default_url(*args)
    # For Rails 3.1+ asset pipeline compatibility:
    ActionController::Base.helpers.asset_path("fallback/" +[version_name, "default.png"].compact.join('_'))
    # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  end
```

- `assets/images`配下に画像を設置（'default.png'にする）
![スクリーンショット 2021-05-24 13.13.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/50b643fb-e8d2-9d6f-371c-86aa5913ed1c.png)

- Viewの設定

```show.html.erb
<% if @user.profile_image? %>
  <%= image_tag @user.profile_image.url %>
<% else %>
  <%= image_tag("default.png") %>
<% end %>
```
※今回のように、`app/assets/images/default.png`とする場合は、`image_tag`ヘルパーメソッドを使用しましょう！<img> タグだと表示できない不具合はあるみたいです！

これで、デフォルト画像が表示されたと思います！
![スクリーンショット 2021-05-24 13.23.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/eebdf52d-4953-1358-12cb-3d3931d4ba32.png)


### 12.画像を加工する（※デフォルト画像は、元々200ｘ250の大きさです。）

- `imagemagick`を導入するため、ターミナルで下記コマンドを実施

```
$ brew install imagemagick
$ brew link --force imagemagick
```
※インストール済みかどうかが分からない場合は，`ターミナルから brew list | grep imagemagick` を実行。 imagemagick が表示されればインストール済みです。

-  `MiniMagick` をGemに導入

```
# Gemfileに追加
gem 'mini_magick'
```
```
 $ bundle install
```
rails cで、サーバーを再起動しましょう。

```app/uploaders/image_uploader.rb
# 次の箇所のコメントアウトを解除
include CarrierWave::MiniMagick
```
- 今回は、200ｘ200に設定したいので、下記を追加

```app/uploaders/image_uploader.rb
process resize_to_fit: [200, 200]
```
これで、大きかった画像が、200x200になりました!
![スクリーンショット 2021-05-24 15.34.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/3129af91-f099-76aa-2b60-321136a4c89b.png)

## まとめ
ここまで、読んで下さってありがとうございます！色々デフォルト画像の所は、特につまってしまったので、同じように悩んでいる方の参考となると幸いです:relaxed:


## 参考記事
- [carrierwaveuploader-GitHub](https://github.com/carrierwaveuploader/carrierwave)
- [[Rails6.0.2]CarrierWaveを基本に忠実に使ってみる](https://yuruli.info/using-carrierwave-on-rails-6/)
- [tigrish/devise-i18n](https://github.com/tigrish/devise-i18n)
- [image_tag | Railsドキュメント](https://railsdoc.com/page/image_tag)
- [CarrierWave【公式ドキュメント】](https://rubydoc.info/gems/carrierwave/frames#processing-methods-mini_magick)