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

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

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

Ruby on Rails バージョン3.1.0はRuby on Railsの特定のバージョンです。2011年8月30日にリリースされました。

Q&A

1回答

438閲覧

ProgateのQuest(Ruby Rails)でのエラーコードの修正

layout

総合スコア0

Ruby on Rails 3.1

Ruby on Rails バージョン3.1.0はRuby on Railsの特定のバージョンです。2011年8月30日にリリースされました。

0グッド

0クリップ

投稿2022/10/02 02:38

前提

オンラインプログラミング学習サイト、Progateの道場レッスンQuestの1ページ目をしています。
回答がないため、正解が分かりません。

実現したいこと

・ログインしていない状態で
/users/1/likes
にアクセスしたときに
/login
にリダイレクトする

・リダイレクトしたときに
ログインが必要です
というFlashメッセージを表示する

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

NoMethodError in Users#likes Showing /home/progate/tweet_app/app/views/users/likes.html.erb where line #7 raised: undefined method `id' for nil:NilClass Extracted source (around line #7): <h2><%= @user.name %></h2> <p><%= @user.email %></p> <% if @user.id == @current_user.id %>(エラーとされているのはここの部分) <%= link_to("編集", "/users/#{@user.id}/edit") %> <% end %> </div>

該当のソースコード

Ruby on rails

試したこと

NoMethodErrorを調べたところ、コントロールにメソッドを定義していないと出ていたのですが

・Application_Controller

class ApplicationController < ActionController::Base
before_action :set_current_user

def set_current_user
@current_user = User.find_by(id: session[:user_id])
end

def authenticate_user
if @current_user == nil
flash[:notice] = "ログインが必要です"
redirect_to("/login")
end
end

def forbid_login_user
if @current_user
flash[:notice] = "すでにログインしています"
redirect_to("/posts/index")
end
end

end

・User_Controller

class UsersController < ApplicationController
before_action :authenticate_user, {only: [:index, :show, :edit, :update]}
before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}
before_action :ensure_correct_user, {only: [:edit, :update]}

def index
@users = User.all
end

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

def new
@user = User.new
end

def create
@user = User.new(
name: params[:name],
email: params[:email],
image_name: "default_user.jpg",
password: params[:password]
)
if @user.save
session[:user_id] = @user.id
flash[:notice] = "ユーザー登録が完了しました"
redirect_to("/users/#{@user.id}")
else
render("users/new")
end
end

def edit
@user = User.find_by(id: params[:id])
end

def update
@user = User.find_by(id: params[:id])
@user.name = params[:name]
@user.email = params[:email]

if params[:image] @user.image_name = "#{@user.id}.jpg" image = params[:image] File.binwrite("public/user_images/#{@user.image_name}", image.read) end if @user.save flash[:notice] = "ユーザー情報を編集しました" redirect_to("/users/#{@user.id}") else render("users/edit") end

end

def login_form
end

def login
@user = User.find_by(email: params[:email])
if @user && @user.authenticate(params[:password])
session[:user_id] = @user.id
flash[:notice] = "ログインしました"
redirect_to("/posts/index")
else
@error_message = "メールアドレスまたはパスワードが間違っています"
@email = params[:email]
@password = params[:password]
render("users/login_form")
end
end

def logout
session[:user_id] = nil
flash[:notice] = "ログアウトしました"
redirect_to("/login")
end

def likes
@user = User.find_by(id: params[:id])
@likes = Like.where(user_id: @user.id)
end

def ensure_correct_user
if @current_user.id != params[:id].to_i
flash[:notice] = "権限がありません"
redirect_to("/posts/index")
end
end

end

で、
def forbid_login_user
if @current_user
flash[:notice] = "すでにログインしています"
redirect_to("/posts/index")
end
end
がUser_Controllerが継承しているAuthonticate_Controllerで定義されているため、
このままでも要求された動きをするはずなのですが
どこが間違っているのでしょうか。

ちなみにルーティングも
get "users/:id/likes" => "users#likes"
です。

何か必要な事項などがありましたらお教えください。

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

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

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

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

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

guest

回答1

0

解決済みかもしれませんが

undefined method `id' for nil:NilClass

とあるのでUserが取得出来てないように見受けられます。

投稿2022/10/02 09:08

sirayusan

総合スコア4

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

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

sirayusan

2022/10/02 09:21 編集

showメソッドの params[:id]に値が入っているかを確認すれば解決しそうです。 あとfind_byでも良いのですが idカラムで絞り込むだけなら @user = User.find(params[:id]) とした方がコードスッキリしますね。 https://www.sejuku.net/blog/13000
layout

2022/10/02 09:36

Application_Controllerの authenticate_userは user_controllerのShowにも継承されて適用されているようですが @user = User.find_by(id: params[:id])の書き方がダメなのか Showアクションの中のUser.find_by(id: params[:id])paramsの前にparams[:id]の値の有無を確認する 動作を入れるべきでしょうか。
sirayusan

2022/10/03 08:51

ちょっと見辛いので ファイルごとにマークダウン分けて、丸々コピペして貰っても良いですか? ファイルA マークダウンの中に記述 ファイルB マークダウンの中に記述 みたいな感じで。
layout

2022/10/03 10:48

マークダウンの中に記述とは、どのような書き方ですか? マークアップ・マークダウンはHTMLの記述だったと思いますが Rubyでもできるのでしょうか
yudukikun5120

2022/10/07 20:59

Teratailの上記の質問をマークダウンで書けということと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問