【Rails】ユーザープロフィール画像機能の実装（Carrierwave）

# 目的
Railsで作成したアプリに`Carrierwave`を用いてユーザープロフィール画像機能を追加する。

# 開発環境
macOS: *Big Sur*
Rubyバージョン: *2.6.5*
Railsバージョン: *6.0.0*

# 前提
- アプリを作成済み。
- `devise`を導入済み。
[【Rails】ユーザー管理機能(devise)の導入](https://qiita.com/oak1331/items/0759bd297e9fd3b81ed2)
- `MiniMagick`を導入済み。
[【Rails】画像アップロード機能の導入](https://qiita.com/oak1331/items/81c7d925e25d0e6fa629)

# 手順

1. [Carrierwaveとは](#carrierwaveとは)
1. [保存画像の設定](#保存画像の設定)
1. [Carrierwaveのインストール](#carrierwaveのインストール)
1. [画像アップロード用カラムの追加](#画像アップロード用カラムの追加)
1. [アップローダークラスの生成](#アップローダークラスの生成)
1. [アップローダーのマウント](#アップローダーのマウント)
1. [ストロングパラメーターの定義](#ストロングパラメーターの定義)
1. [画像の表示](#画像の表示)
1. [画像サイズの変更](#画像サイズの変更)

# Carrierwaveとは

`Carrierwave`とは画像をアップロード機能を簡単に追加してくれるGemの事です。

# 保存画像の設定

`Carrierwave`を使用して投稿される画像は、`「public/uploads/モデル名/画像のカラム名/id」`以下に溜まっていきます。
今回は画像をGitで管理する必要が無いため、管理下から除外します!

```:.gitignore
# .gitignoreへ追加
/public/uploads
```

これでGitで管理しない設定ができました。

# Carrierwaveのインストール

次にCarrierwaveをインストールします。

```ruby:app/Gemfile
#省略
gem 'carrierwave'
```

```:ターミナル
% bundle install
```

これでインストールできました!

# 画像アップロード用カラムの追加

ここで画像アップロード用のカラムを追加します。
このカラムは、`「画像のデータ」`ではなく`「画像のファイル名」`を保存するためのものです。

画像データを保存すると、データベースサーバーの要領が圧迫するため、どの画像ファイルか確認するためのファイル名だけを保存します。

```:ターミナル
% rails g migration AddAvatarToUsers avatar:string
```

```:ターミナル
% rails db:migrate
```

今回カラム名は`avatar`としました。

# アップローダークラスの生成

アップローダークラスでは、アップロードするファイルの拡張子やサイズ、保存するパスを指定する事が出来ます。

```:ターミナル
% rails g uploader avatar
```

上記を実行することで,`「app/uploader/avatar_uploader.rb」`がつくられます。

# アップローダーのマウント

次に、「アップロード画像用のカラム」と「アップローダークラス」を紐づける為に、`「avatar_uploader」`をマウントします。

```ruby:app/models/user.rb
class User < ActiveRecord::Base
  mount_uploader :avatar, AvatarUploader
end
```

これでアバター画像をアップロードする際に、`AvatarUploaderクラス`の設定を利用出来る様になりました。

# ストロングパラメーターの定義

ストロングパラメーターを設定して、画像ファイル名の保存を許可します。

```ruby:app/controller/users_controller.rb
#省略
def update
  if @user.update(user_params)
    redirect_to root_path
  else
    render :edit
  end
end
#省略
private
def user_params
  params.require(:user).permit(:name, :email, :avatar)
end
```

`devise`を使用しているので、新規登録時にもプロフィール画像が設定できるように、
ストロングパラメーターを定義します。

```ruby:app/controller/applicarion_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :avatar])
  end
end
```

これで`「新規登録時」`と`「アカウント編集時」`にプロフィール画像が設定できるようになりました！

# 画像の表示

次にビューファイルの編集です。
まずはユーザー設定画面に下記のように記述します。

```html:.html.erb
<div class="field">
  <%= f.label :avatar %>
  <%= f.file_field :avatar %>
</div>
```

次はプロフィール画像の表示です。

```html:.html.erb
<% if @user.avatar? %>
  <%= image_tag @user.avatar.url %>
<% else %>
  <%= image_tag ("noavatar.png") %>
<% end %>
```

画像がある場合は、画像ファイルのURLを取得し表示させ、無い場合はデフォルト画像を表示させます。

# 画像サイズの変更

最後に`avatar_uploader.rb`を編集して、MiniMagick経由で画像のリサイズを行えるようにします!

```ruby:app/uploaders/avatar_uploder.rb
class AvatarUploader < CarrierWave::Uploader::Base 
  include CarrierWave::MiniMagick
  process resize_to_fit: [100, 100]
end
```

`resize_to_fit`は縦横比を維持したまま、縦横を指定したサイズ以内にリサイズするという意味です。

# 最後に

以上でユーザープロフィール画像機能の実装は完了です。
アプリ制作の際は、画像アップロード機能を導入済みであれば簡単に実装できるので、ぜひ試してみてください。
では。