[Ruby] [Ruby on Rails] Follow function undefined method `id’ for nil:NilClass

2 minute read

![Screenshot 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)

Assumptions/what you want to achieve

I want to implement the follow function. ruby 2.5.1p57 Rails 5.2.4.2

The following error message occurred while implementing the follow function.

The problem/error message you are experiencing

error


undefined method `id' for nil:NilClass

Applicable source code

table (migration file)

relationships table


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

model

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

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

Routing

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

Views

ruby:_follow_form.html.haml


- unless current_user?(@user)
  #follow_form
  -if current_user.following?(@user)
    = render'unfollow'
  -else
    = render'follow'

Controller

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

What I tried

・Confirmed whether the association of user.rb (user model) is set correctly. ・I thoroughly checked whether there were any misspellings in user.rb (user model) and _follow_form.html.haml (partial template).

Meaning of error message

error


following_relationships.find_by(following_id: user.id)

undefined method `id' for nil:NilClass

・I tried to call the id method on nil but it was not found ・User is nil

→ What causes the user to become nil? ? ?

Discovered error cause and solution

  • @User was not defined in the show action of users_controller.rb. Since it is displayed as NoMethodError in Users#show on the error screen, it was the show action of users_controller.rb that should be suspected.

I solved it by defining @user as follows in the show action of users_controller.rb.

users_controller.rb


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

In params[:id], the value sent with the path from the screen before transition is received.

Thanks to this article for being able to resolve the error

I found it on a wisdom-like site called teratail, an engineer’s yahoo. [Ruby on Rails] Follow function undefined method `id’ for nil:NilClass error message appears