【Railsチュートリアル】プロフィール画像をアプリ内で設定できるように変更

#はじめに

Railsチュートリアル第6版sample_appにおいて、プロフィール画像にはgravatarが使用されているが、プロフィール画像をアプリ内で設定できるようにしていく。

**前提**
第6版sample_appが完成している

#初期画像を設定#

usersテーブルにimage_nameカラムを追加する。

```
$ rails g migration add_image_name_to_users
```

```rb:db/migrate/[timestamp]_add_image_name_to_users.rb
class AddImageNameToUsers < ActiveRecord::Migration[6.1]
  def change
    add_column :users, :image_name, :string
  end
end
```

```
$ rails db:migrate
```

初期画像default_user.jpgをapp/assets/imagesディレクトリ下に用意しておく。

```
├ app/
    ├ assets/
           ├ images/
　　　　　　　　　　　　　　　　　　　　        └ default_user.jpg
```

ユーザー登録時にimage_nameの値がdefault_user.jpgになるように設定。

```rb:app/controllers/users_controller.rb
  .
  .
  .
  def create
    @user = User.new(user_params)
    @user.image_name = "default_user.jpg"
    if @user.save
      @user.send_activation_email
      flash[:info] = "Please check your email to activate your account."
      redirect_to root_url
    else
      render 'new'
    end
  end
  .
  .
  .
```

#ユーザー編集画面で画像変更を可能にする#

ユーザー編集のビューを変更する。
このとき、画像をうけつけるためにform_withにmultipart: trueを記述する。
また、今回は画像表示にimage_tagを使用する。

```rb:app/views/users/edit.html.erb
    .
    .
    .
    <%= form_with(model: @user, local: true, multipart: true) do |f| %>
    .
    .
    .
      <%= image_tag @user.image_name, width: "100px", height: "100px", class:"icon"%>
      <%= f.label :image, "Icon change" %>
      <%= f.file_field :image, class: 'form-control' %>

      <%= f.submit "Save changes", class: "btn btn-primary" %>
    <% end %>

  </div>
</div>
```

送信した画像を受け取るためにコントローラーを編集する。

```rb:app/controllers/users_controller.rb
  .
  .
  .
  def update
    @user = User.find(params[:id])
    if params[:user][:image]
      @user.image_name = "#{@user.id}.jpg"
      image = params[:user][:image]
      File.binwrite("app/assets/images/#{@user.image_name}",image.read)
    end
    if @user.update(user_params)
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end
  .
  .
  .
```

以下のようになっていれば成功。

![スクリーンショット 2021-11-23 21.07.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2200191/71069914-e66d-dcc1-9d49-b488b972ca7c.png)

#画像を表示する

gravatarで表示していたビューをimage_tagに変更していく。
編集するビューは以下。

- views/microposts/micropost.html.erb
- views/shared/_user_info.html.erb
- views/users/_user.html.erb
- views/users/edit.html.erb
- views/users/show_follow.html.erb
- views/users/show.html.erb

例えば

```rb:views/microposts/micropost.html.erb
<%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
```

を

```rb:views/microposts/micropost.html.erb
<%= link_to image_tag(micropost.user.image_name, width: "50px", height: "50px", class:"icon"), micropost.user%>
```

というように変更する。

最後にcssを変更する。
自分は画像を丸く表示させたかったので以下のように記述。

```rb:app/assets/stylesheets/custom.scss
.
.
.
.icon {
  border-radius: 50%;
  object-fit: cover;
  float: left;
  margin-right: 10px;
}
```

以下のようになっていれば成功。

![スクリーンショット 2021-11-23 21.31.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2200191/70362c68-5649-a605-5912-2025a99c83d7.png)

#発生するエラーについて
自分は開発環境に[Rails×RSpec×Docker×CircleCI](https://qiita.com/supyolo888/items/14ee51c4e4cac2d39757)を使用しており、開発環境ではうまくいくが、herokuにデプロイ後ユーザー編集画面でプロフィール画像を変更しようとすると、
![20181016180215.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2200191/6c2c83d4-b996-d76b-dc62-6c0c38ea2a10.png)
こちらのエラーが発生する。
ログを見てみるとどうやらアセットパイプラインに関してのエラーが発生しているようであり、production.rbに

```rb:config/environments/production.rb
config.assets.compile = true
```

を追加したりしてみたが改善されなかったため、carrierwaveを用いた方法に変更することにした。
[記事はこちら](https://qiita.com/supyolo888/items/c1073ada0b04fb2f9e7f)