質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

5328閲覧

rails での undefined method `id' for nil:NilClass エラーの解決方法を教えてください。

ken-1

総合スコア1

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2020/06/15 09:22

前提・実現したいこと

初学者です。
railsで投稿アプリを作っています。
show.htmlページ上に設置したリンクから
記事の編集または削除を行うと同じエラーが発生してしまいます。

発生している問題・エラーメッセージ

NoMethodError at /posts/index undefined method `id' for nil:NilClass

該当のソースコード

routes

1Rails.application.routes.draw do 2 root "home#top" 3 get "/about", to: "home#about" 4 get "/signup", to: "users#new" 5 get "/login", to: "sessions#new" 6 post "/login", to: "sessions#create" 7 delete "/logout", to: "sessions#destroy" 8 post "/likes/:post_id/create", to: "likes#create" 9 delete "/likes/:post_id/destroy", to: "likes#destroy" 10 get "/users/:id/likes", to: "users#likes" 11 resources :users do 12 member do 13 get :following, :followers 14 end 15 end 16 resources :posts do 17 resources :comments, only: [:create, :destroy] 18 end 19 resources :relationships, only: [:create, :destroy] 20end 21

controller

1class PostsController < ApplicationController 2 before_action :logged_in_user, only: [:index, :show, :create, :edit, :update, :destroy] 3 before_action :correct_user, only: [:update, :destroy] 4 5 def index 6 @posts = Post.all.paginate(page: params[:page], per_page: 10) 7 end 8 9 def show 10 @post = Post.find_by(id: params[:id]) 11 @likes_count = Like.where(post_id: @post.id).count 12 end 13 14 def new 15 @post = Post.new 16 end 17 18 def create 19 @post = current_user.posts.build(post_params) 20 if @post.save 21 flash[:success] = "投稿しました" 22 redirect_to posts_url 23 else 24 render "new" 25 end 26 end 27 28 def edit 29 @post = Post.find_by(id: params[:id]) 30 end 31 32 def update 33 if @post.update_attributes(post_params) 34 flash[:success] = "投稿を更新しました" 35 redirect_to("/posts/index") 36 else 37 render "edit" 38 end 39 end 40 41 def destroy 42 @post.destroy 43 flash[:success] = "投稿を削除しました" 44 redirect_to request.referrer || root_url 45 end 46 47 private 48 49 def post_params 50 params.require(:post).permit(:content, :image, :answer) 51 end 52 53 def correct_user 54 @post = current_user.posts.find_by(id: params[:id]) 55 redirect_to root_url if @post.nil? 56 end 57end 58

view

1<% provide(:title, '詳細ページ') %> 2<h1>クイズの詳細ページ</h1> 3<div class="row"> 4 <div class="col-lg-8 offset-2"> 5 <div class="post-user-name"> 6 <%= image_tag @post.user.image.url(:thumb) if @post.user.image? %> 7 <%= link_to(@post.user.name, "/users/#{@post.user.id}") %> 8 </div> 9 <p><%= @post.content %></p> 10 <p><%= image_tag @post.image.url if @post.image? %></p> 11 <%= render 'answer' %> 12 投稿 <%= time_ago_in_words(@post.created_at) %> 前 13 <div class="post-time"> 14 <%= @post.created_at %> 15 </div> 16 <% if current_user?(@post.user) %> 17 <div class="post-menus"> 18 <%= link_to "編集", edit_post_path(@post.id) %> 19 <%= link_to "削除", post_path(@post.id), method: :delete, data: { confirm: "本当によろしいですか?" } %> 20 </div> 21 <% end %> 22 <% if !current_user?(@post.user) %> 23 <% if Like.find_by(user_id: current_user.id, post_id: @post.id) %> 24 <%= link_to("/likes/#{@post.id}/destroy", {method: "delete"}) do %> 25 <span class="fa fa-heart like-btn-unlike"></span> 26 <% end %> 27 <% else %> 28 <%= link_to("/likes/#{@post.id}/create", {method: "post"}) do %> 29 <span class="fa fa-heart like-btn"></span> 30 <% end %> 31 <% end %> 32 <%= @likes_count %> 33 <h3 class="mt-5">コメント</h3> 34 <% if @post.comments.any? %> 35 <ul> 36 <% @post.comments.each do |comment| %> 37 <li> 38 <%= comment.body %> 39 <%= link_to "削除", post_comment_path(@post, comment), 40 method: :delete, class: "command", data: { confirm: "sure?" } %> 41 </li> 42 </ul> 43 <% end %> 44 <% end %> 45 <%= form_for([@post, @post.comments.build]) do |f| %> 46 <%= f.text_field :body %> 47 <%= f.submit "投稿する", class: "btn" %> 48 <% end %> 49 <% end %> 50 </div> 51</div>

helper

1module SessionsHelper 2 3 def log_in(user) 4 session[:user_id] = user.id 5 end 6 7 def current_user?(user) 8 user == current_user 9 end 10 11 def current_user 12 if session[:user_id] 13 @current_user ||= User.find_by(id: session[:user_id]) 14 end 15 end 16 17 def logged_in? 18 !current_user.nil? 19 end 20 21 def log_out 22 session.delete(:user_id) 23 @current_user = nil 24 end 25end

log

1Started GET "/posts/index" for ::1 at 2020-06-15 17:23:17 +0900 2Processing by PostsController#show as HTML 3 Parameters: {"id"=>"index"} 4 User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? 5 [["id", 1], ["LIMIT", 1]] 6 ↳ app/helpers/sessions_helper.rb:13 7 Post Load (0.3ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? ORDER BY "posts"."created_at" DESC LIMIT ? [["id", 0], ["LIMIT", 1]] 8 ↳ app/controllers/posts_controller.rb:10 9Completed 500 Internal Server Error in 20ms (ActiveRecord: 0.7ms) 10 11 12 13NoMethodError - undefined method `id' for nil:NilClass: 14 app/controllers/posts_controller.rb:12:in `show' 15 16Started POST "/__better_errors/fc7af7b58a0213f4/variables" for ::1 at 2020-06-15 17:23:17 +0900

試したこと

updateやdestroyアクションを行うことでエラーが発生していますが、エラー箇所はcontrollerのshowアクションで起きています。
def show
@post = Post.find_by(id: params[:id])
@likes_count = Like.where(post_id: @post.id).count   <= ここ
end
エラー画面から「戻る」の後、showページをリロードするとなぜか更新や削除が実行されています。
エラーメッセージでは、idがnilになっているとのことですが、デバッグでは@postがnilになってしまっているようです。
単純なエラーのような気がしますが、1日検索したり考えてみましたが、解決策が分からずにいます。
独学でやっておりますので、分らないことが多く大変恐縮ですが、アドバイスいただけると幸いです。
よろしくお願い致します。

補足情報(FW/ツールのバージョンなど)

$ ruby -v
ruby 2.6.6p146 (2020-03-31 revision 67876) [x64-mingw32]
$ rails -v
Rails 5.2.4.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

redirect_to("/posts/index")

ruby

1redirect_to("/posts")

かな

投稿2020/06/15 09:29

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ken-1

2020/06/15 09:39

asm様 早速のアドバイスありがとうございます。 updeate、 destroy 共に redirect_to("/posts") にしたところ、エラーも出ずに実行することができました。 正直どうしてなのか分かりません。 できたら理由などを教えていただけませんでしょうか。
maisumakun

2020/06/15 09:40

> 正直どうしてなのか分かりません。 /posts/indexは、PostsController#showを、id=indexという値で呼ぶことになります。もちろんこんなIDは見つかりません。
ken-1

2020/06/15 10:23

たびたびありがとうございます。 redirect_toは、/post/indexなどのURLにページ移動するという認識だったので、、、なぜcontroller#showをid=indexという値で呼ぶのかの理解に苦しんでいます。 仕組みが全然理解できていないのだろうと、リダイレクトについてググってみましたが分かりませんでした。 お手数ですがそのあたりも教えていただけると助かります。
maisumakun

2020/06/15 10:32 編集

> redirect_toは、/post/indexなどのURLにページ移動するという認識だったので そのとおりです。「/post/index」というURLにアクセスすると、すでに書いたコメントのような動作をします。
asm

2020/06/15 11:12

「bin/rails routes」コマンドなどでURLが各コントローラにどのようにマッピングされているかが表示されますので 眺めてみるのも勉強になるかと思います。 developmentモードの場合 http://localhost:3000/rails/info/routes にアクセスすることでも表示されます。
ken-1

2020/06/15 11:41

参考になりました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問