LoginSignup
2
6

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-06-20

エラー画面

スクリーンショット 2020-06-20 06.55.37.png

実現したいこと

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

エラーメッセージ

undefined method `id' for nil:NilClass

該当のソースコード

テーブル(マイグレーションファイル)

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

モデル

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

ルーティング

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

ビュー

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

コントローラー

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(部分テンプレート)のスペルミスがないかをくまなく確認した。

エラーメッセージの意味

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を定義して解決した。

解決方法

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

params[:id]で、遷移前の画面からパスと一緒に送信された値を受け取っている。

参考記事

【Ruby on Rails】フォロー機能 undefined method `id' for nil:NilClassというエラーメッセージが出る

2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6