【Rails】Twitterクローンを作ってみた 〜ユーザー詳細ページの作成〜

## はじめに
[【Rails】Twitterクローンを作ってみた 〜ログイン周り編〜](https://qiita.com/bloom__fu/items/d005686cbdaa83d2c0c2)の続きです。ログイン周り編を前提に進めていきますので、まだご覧になっていない方はそちらからご覧ください！※こちらはdockerでの環境構築を省きます。
## サービス環境
- ruby 3.0.0
- Rails 6.0.4
- docker
- mysql 8.0.2
- Slim, SCSS

## ユーザー詳細ページの作成
#### 条件
- トップページの「つぶやく」の上にある自分の名前をクリックするとユーザー詳細ページに飛ぶ
- 自分のプロフィールを編集できる
- 退会ボタンから退会することができる
ユーザーのプロフィールの内訳は名前、自己紹介文、プロフィール画像とします。プロフィール画像に関しては後のセクションでやるのでまだこのセクションでは編集できなくて良いです。ユーザー退会はユーザーを実際に削除するのではなく論理削除してください。
#### 実装流れ(簡略)
① Userモデルに紐付けたProfileモデル作成(nameカラムとprofile_textカラムを持つ)
② db:migrate、userモデル編集(has_one :profile, dependent: :destroy)
③ profilesコントローラ作成
④ profilesコントローラの中身を書いていく ← 重要！
⑤ profile周りの見た目を作成
⑥ userクラスにdelete_atカラムを追加(rails g migration)
⑦ db:migrate
⑧ registrationsコントローラ内のオーバーライド(+α サインアップ後、プロフィール登録ページに遷移するようにする)
⑨ userモデル編集(論理削除)
#### サインアップ後のプロフィール登録ページ
![スクリーンショット 2022-10-24 22.27.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1961802/72a59237-cc1e-2240-f751-6beea881e114.png)

#### プロフィール編集画面

![スクリーンショット 2022-10-24 22.32.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1961802/86e1607a-43ff-57c6-0f26-0441c2985362.png)

#### TOPページ
![スクリーンショット 2022-10-24 22.34.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1961802/2f31d33b-68c9-4853-4b8f-518cb7b6e4ba.png)

## 解説
#### profiles_controller.rb
```ruby
class ProfilesController < ApplicationController
  before_action :find_profile, only: [:show, :edit]
  
  def new
    return redirect_to edit_profile_path(current_user) unless current_user.profile.blank?
    @profile = Profile.new
  end
  
  def edit
    redirect_to root_path unless @user.id == current_user.id
  end

  def show
  end

  def create
    @profile = current_user.build_profile(profile_params)
    if @profile.save
      redirect_to root_path, notice: "プロフィールを作成しました"
    else
      render :new
    end
  end

  def update
    @profile = current_user.profile
    
    if @profile.update(profile_params)
      redirect_to profile_path(current_user), notice: "プロフィールを更新しました"
    else 
      render :edit
    end
  end

  def destroy
  end

  private

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

  def profile_params
    params.require(:profile).permit(
      :name, :profile_text, :image
    )
  end
end

```
privateでのfind_profileメソッドにかなり時間を取られました。リファクタリングする前は、params[:id]をcurrent_user.idで取得しており、この場合だと他の人のプロフィールが見れないとコードレビューをいただき、たしかになと学びました。さらには、editアクションでログインしているユーザー以外が編集できないように下記のコードを書きました。
```ruby
redirect_to root_path unless @user.id == current_user.id
```
updateメソッドでは、取得するidはcurrent_user.idですね。
```ruby
@profile = current_user.profile
```
これは
```ruby
@user = User.find(current_user.id)
@profile = @user.profile
```
に同じですね。
最後にbuildメソッドの解説です。buildメソッドとは、インスタンスを生成するメソッドです。インスタンスを生成するメソッドは他にnewメソッドがありますが、buildメソッドとの違いはありません。暗黙の了解で、モデルを関連付けした時にはbuildを使うみたいな感じになっています。ここでのモデルのアソシエーションは1対1の関係なので「build_関連付けのメソッド名」として利用できます。1対多、多対多の場合では、「関連付けメソッド名.build」となります。


## 実装を通して学んだこと
#### 1. idの取得
ログインが絡むidの取得には、ログインしているユーザーだけができる操作と、ログインユーザーを含めた全てのユーザーができる操作というものを分けて考えてコードに反映させることが大事だなと学びました。基本的なことですが、ここがしっかりしていないとログインの意味がないですもんね。
#### 2. モデルへの紐づけ
モデルとのアソシエーションがどういう関係にあるのかということ。modelを作成するときにreferencesを使い、暗黙の了解で、モデルを関連付けした時にはコントローラ内でbuildを使うことを学びました。
#### 3. 論理削除
deviseで作成したUserモデルのregistrations_controller.rbにDevise registrations controllerを継承し、destroyアクションをオーバーライドすることを学びました。routes.rbで削除時のroutingをオーバーライド。論理削除でユーザーモデルを更新し、認証でユーザーがアクティブかどうかを確認することを学びました。
## 感想
今回の実装はprofilesコントローラの中身を書くことにより、railsでの論理的な考えが学べました！実際にコードを見ると簡単ですが、コードを書いている際は、エラーが出て該当部分を修正してといった感じで一筋縄では行かなかったです。論理削除は過去の論理削除の記事を参考にして、どのコントローラにオーバーライドするのか、modelへの記述の仕方を勉強することができました！よくudemyでモデルへの紐づけのやり方を見ていましたが、初めて実装してみて、やっとアウトプットできたなといった感想です。次回のセクションも紐づけを行うため練習になりました。
次回は**ツイート機能の作成**についてアウトプットしていこうと思います！読んでいただきありがとうございました。
## 参考記事
- https://qiita.com/tatsuhiko-nakayama/items/0dc982b123e9d7721d3d
- https://qiita.com/t1gert1ger/items/0b90040085005f0860bf
- https://techtechmedia.com/build-method-rails/