RailsでCarrierWaveとRMagickを使い、円形のプロフィール画像を実装する方法

#Carrierwaveとは
画像ファイルのアップロード機能を簡単に追加する事が出来るgemです。

#RMgickとは
画像ファイルのサイズの変更や画像の中心切り取りなどができます。
長方形の画像でも綺麗な正方形の画像にできます。
（中心から指定したサイズで抜き取ることが可能なため）

※他に**minimagick**という画像ファイルのサイズの変更ができるgemがありますが、今回は取り扱いません。

#バージョン
Ruby 2.7.0
Rails 6.0.2.1
carrierwave 2.1.0
rmagick 4.0.0

#手順１・Carrierwaveを導入する
まず下記のgemをインストールします

```Gemfile.
gem 'carrierwave'
```
そして`bundle install`します。
その後`rails g uploader image`でアップローダーを作成します。



```ターミナル.
＄ bundle install

＄ rails g uploader image

app/uploaders/image_uploader.rb //ファイルが作成されます
```

imageカラムがない場合は作成しなければなりません。
今回はプロフィール画像なのでuserモデルに作成します。

```ターミナル.
$ rails g migration AddImageToUsers image:string

$ rails db:migrate
```
これでuserモデルにimageカラムができました。

次に追加したuserモデルの`user.rb`を編集し`image_uploader`に関する記述をします。


```user.rb
class User < ApplicationRecord
  #省略

  mount_uploader :image, ImageUploader #追加
end
```
以上でCarrierWaveの導入は終了です。

#手順２・RMagickを導入する
初めに言っておきますがRMagickの導入はとてもややこしいです。笑
ですがしっかり順番通りにやれば問題なく導入できますのでご安心ください。

まずはじめに、ImageMagick 6 と pkg-configをインストールします。
以下を順に実行。

```ターミナル.
$ brew install imagemagick@6

$ brew install pkg-config
```
次に以下を実行

```ターミナル.
$ export PKG_CONFIG_PATH=/usr/local/opt/imagemagick@6/lib/pkgconfig
```
最後に、gemコマンドで `rmagick` をインストールします。

```ターミナル.
$ gem install rmagick
```
これでようやくgemをインストールする準備が整いました。
`Gemfile`に以下を追加。

```Gemfile.
gem 'rmagick'
```

bundle installを実行

```ターミナル.
$ bundle install
```
以上でRMagickの導入も終了です。

#手順３・`image_uploader.rb`に記述
最初の方に作成したファイル`image_uploader.rb`に下記を記述

```image_uploader.rb
  version :thumb do
    process :resize_to_fill => [width, height, gravity = ::Magick::CenterGravity]
  end

  #widthとheightにそれぞれ横幅と高さの数値をいれる。同じ数値を入れれば正方形になる。
  #下記の例の場合は２００pxの正方形になる。
  #【例】
  #version :thumb do
    #process :resize_to_fill => [２００, ２００, gravity = ::Magick::CenterGravity]
  #end
```
これで画像を正方形にすることができます。

次に画像の反転を防ぐ記述をします。

```image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  #省略

  def auto
    manipulate! do|image|
      image.auto_orient
    end
  end

  process :auto

 #省略
end
```

#手順４・モデルの記述
今回はユーザーのプロフィール写真なのでuserモデルに記述します。

```user.rb
class User < ApplicationRecord
  #省略

  mount_uploader :image, ImageUploader
end
```
これでモデルの関連付けができました。

#手順５・コントローラーの記述
次にコントローラーに記述していきます。

```users_controller.rb
class UsersController < ApplicationController
  #省略

  def show
    @user = User.find(params[:id])
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    if @user.id == current_user.id
      @user.update(user_params)
      flash[:success] = "プロフィールが更新されました！"
      redirect_to user_path(@user)
    else
      render 'edit'
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :image)
  end 
end
```
※ストロングパラメーターの部分はご自身のカラムに応じて変更してください。

#手順６・ビューの実装

次にビューに実装してきます。

```erb:edit.html.erb
 <% if @user.image? %>
   <%= image_tag @user.image.thumb.url, class: "user-icon" %>
 <% else %>
   <%= image_tag "default.jpg", alt: "user-icon", size: "200", class: "user-icon" %>
 <% end %>
 <button type="button" class="btn btn-outline-secondary rounded-pill">
   <%= f.file_field :image, accept: 'image/jpeg,image/gif,image/png', class: "image-select-btn" %>
 </button>
```
※4行目の`size: "200"`で200pxの正方形のデフォルト画像になります。


`<% if @user.image? %>`でプロフィール写真をアップロードしていればそれが表示され、なければ、デフォルト画像を表示する形になっています。
デフォルト画像は`app/assets/images`の中に入れておきましょう。

ちなみに

```erb:edit.html.erb
<%= image_tag "/assets/images/default.jpg", alt: "user-icon", size: "200", class: "user-icon" %>
```
と書くとエラーになりますのでご注意ください。

`edit.html.erb`の解説に戻ります。

2行目の`thumb`を書くことで、先ほど`image_uploader.rb`に記述した内容（widthとheight)が画像に反映されます。

次にCSSで画像を丸くします。

```scss:users.scss
.user-icon {
  border-radius: 100px;
}
```
これでプロフィール画像を丸くすることができました。

プロフィール画像がアップロードされていなければ、下のような実装ができています。
※背景色はデフォルト画像を見やすくするために設定したものです。

![スクリーンショット 2020-09-03 9.30.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614783/b4c77555-8b97-f697-dee1-80a3536a07aa.png)

上の「ファイルを選択」ボタンからプロフィール画像をアップロードできます。

アップロードするとデフォルト画像と同じく円形になっています。

以上で実装は終了になります。

#参考資料
下記の記事を参考に書かせて頂きました。
記事を投稿して下さった方、ありがとうございます。

[画像アップロードCarrierwaveを導入する](https://qiita.com/sakuraniumarete/items/af0869faf2d369005c4e)
[RailsでRMagickを使う](https://qiita.com/yukiweaver/items/52c45f442b9d9d59367e)
[【Rails】CarrierWaveとRMagickでいい感じにサムネイルをつくる](https://qiita.com/hakusai_it/items/fdd1561097645e10cdd5)
[CarrierWaveを使って、ユーザー画像を設定する。](https://qiita.com/nekotanku/items/5da43600f35eada64eac)