エラー画面
実現したいこと
フォロー機能を実装したい。
フォロー機能を実装中に以下のエラーが発生しました。
エラーメッセージ
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というエラーメッセージが出る