【Ruby on Rails】 フォロー機能 undefined method `id' for nil:NilClassというエラーの解決

# エラー画面
![スクリーンショット 2020-06-20 06.55.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/e67b71c9-38e1-7df9-bfd8-8f1dbe9a6724.png)

# 実現したいこと
フォロー機能を実装したい。
フォロー機能を実装中に以下のエラーが発生しました。

# エラーメッセージ

```
undefined method `id' for nil:NilClass
```

# 該当のソースコード

#### テーブル（マイグレーションファイル）

```ruby:relationshipsテーブル
class CreateRelationships < ActiveRecord::Migration[5.2]
  def change
    create_table :relationships do |t|
      t.integer :follower_id, foreign_key: true
      t.integer :following_id, foreign_key: true

      t.timestamps null: false
    end

    add_index :relationships, :follower_id
    add_index :relationships, :following_id
    add_index :relationships, [:follower_id, :following_id], unique: true
  end
end
```

#### モデル
```ruby:relationship.rb
class Relationship < ApplicationRecord
  belongs_to :follower, class_name: "User"
  belongs_to :following, class_name: "User"
  validates :follower_id, presence: true
  validates :following_id, presence: true
end
```

```ruby:user.rb
class User < ApplicationRecord
  devise  :database_authenticatable, :registerable,
          :recoverable, :rememberable, :validatable
  has_many :posts, dependent: :destroy
  has_many :likes, dependent: :destroy
  has_many :liked_posts, through: :likes, source: :post
  has_many :comments
  
  def already_liked?(post)
    self.likes.exists?(post_id: post.id)
  end

  has_many :following_relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy
  has_many :followings, through: :following_relationships, source: :following
  has_many :follower_relationships, class_name: "Relationship", foreign_key: "following_id", dependent: :destroy
  has_many :followers, through: :follower_relationships, source: :follower

  def following?(user)
    following_relationships.find_by(following_id: user.id)
  end

  def follow!(other_user)
    following_relationships.create!(following_id: user.id)
  end

  def unfollow!(other_user)
    following_relationships.find_by(following_id: user.id).destroy
  end
  
end
```

#### ルーティング
```ruby:routes.rb
Rails.application.routes.draw do
  devise_for :users
  root to: "posts#index"

  resources :posts do
    resources :comments, only: :create
    resources :likes, only: [:create, :destroy]
  end

  resources :users do
    member do
      get :following, :followers
    end
  end

  resources :relationships, only: [:create, :destroy]
end
```


#### ビュー
```ruby:_follow_form.html.haml
- unless current_user?(@user)
  #follow_form
  - if current_user.following?(@user)
    = render 'unfollow'
  - else
    = render 'follow'
```
#### コントローラー
```ruby:users_controller.rb
class UsersController < ApplicationController

  def show
    
  end
  
  def edit
    
  end

  def update
    if current_user.update(user_params)
      redirect_to root_path
    else
      render :edit
    end
  end

  def following
    @user = User.find(id: params[:id])
    binding.pry
    @users = @user.followings
    render 'show_following'
  end

  def followers
    @user = User.find(id: params[:id])
    binding.pry
    @users = @user.followers
    render 'show_follower'
  end

  private

  def user_params
    params.require(:user).permit(:id, :name, :email)
  end

end
```

# 試したこと

・user.rb（userモデル）のアソシエーションが正しく組まれているかを確認した。
・user.rb（userモデル）、_follow_form.html.haml（部分テンプレート）のスペルミスがないかをくまなく確認した。

# エラーメッセージの意味
```ruby:error
following_relationships.find_by(following_id: user.id)

undefined method `id' for nil:NilClass
```
- userがnilなので`.id`でidを取得できない。

# エラー原因
- `users_controller.rb`のshowアクションで@userが定義されていなかった。
- エラー画面で`NoMethodError in Users#show`と表示されているので、疑うべきは`users_controller.rb`のshowアクションだった。

`users_controller.rb`のshowアクションで以下のように@userを定義して解決した。

# 解決方法
```ruby:users_controller.rb
def show
  @user = User.find(params[:id])
end
```
`params[:id]`で、遷移前の画面からパスと一緒に送信された値を受け取っている。

# 参考記事
[【Ruby on Rails】フォロー機能 undefined method `id' for nil:NilClassというエラーメッセージが出る](https://teratail.com/questions/235400)