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

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

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

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

解決済

rspecにてundefined method `already_liked?' for nil:NilClass

Engineer_traine
Engineer_traine

総合スコア17

Ruby on Rails

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

2回答

0評価

0クリップ

469閲覧

投稿2021/10/13 08:04

編集2021/10/13 11:42

前提・実現したいこと

現在既存のアプリ(カフェ登録ができるようなアプリ)に対していいね機能を実装したのですが
ローカル環境ではいいね機能もしっかり機能していたのでrspecでテストを行ったところ
タイトルのエラーが発生しました。
恐らくcurrent_userがnilだとはいうことだと思いますがイマイチ現状なぜエラーが発生しているのか
掴めていません。
ちなみにログイン機能を実装した際はgem 'devise'は使用していません。
そのためかcurrent_userが使用できないのかと考えてはいましたが他の箇所でもcurrent_userを
使用していました。
application_controller.rbではdef current_userで定義してあります。
またrspecにてbeforeでログインしていないという動作を怠ったということも考えましたが
ちゃんとログインするような記述はしておりました。
どなたか原因特定できる方もしいましたらご教授お願い致します。

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

1) Caves #show カフェ詳細画面の表示に成功すること Failure/Error: <% if current_user.already_liked?(@cafe) %> ActionView::Template::Error: undefined method `already_liked?' for nil:NilClass # ./app/views/caves/show.html.erb:73:in `_app_views_caves_show_html_erb__3062244970416319179_74500' # ./spec/requests/caves_spec.rb:45:in `block (3 levels) in <main>' # ------------------ # --- Caused by: --- # NoMethodError: # undefined method `already_liked?' for nil:NilClass # ./app/views/caves/show.html.erb:73:in `_app_views_caves_show_html_erb__3062244970416319179_74500'

該当のソースコード

<% provide(:title, "cafe") %> <%= render "shared/login_header" %> <div class="detail_title">カフェ詳細</div> <div class="cafe_detail"> <p class="img_detail"> <% if @cafe.image? %> <%= image_tag @cafe.image.to_s %> <% else %> <p>画像なし</p> <% end %> </p> <div class="cafe_description"> <p class="cafe_item"> <strong> <i class="fas fa-store"></i>店名: </strong> <%= @cafe.name %> </p> <p class="cafe_item"> <strong> <i class="fas fa-map-marker"></i>住所: </strong> <%= @cafe.address %> </p> <%= render 'shared/cafe_map', cafe: @cafe %> <p class="cafe_item"> <strong> <i class="fas fa-clock"></i>営業時間: </strong> <%= @cafe.business_hours.strftime( "%H:%M" ) %>~<%= @cafe.end_business_hours.strftime( "%H:%M" ) %> </p> <p class="cafe_item"> <strong> <i class="fas fa-lightbulb"></i>コンセント席数: </strong> <%= @cafe.number_seats %>席 </p> <p class="cafe_item"> <strong> <i class="fas fa-wifi"></i>Wifi: </strong> <% if @cafe.wifi == true %> <%= @cafe.wifi="◯" %> <% else %> <%= @cafe.wifi="×" %> <% end %> </p> </div> <div class="detail_link"> <%= link_to '更新する', edit_cafe_path(@cafe) %> | <%= link_to '戻る', caves_path %> </div> </div> <div class="detail_comment">コメント一覧</div> <div class="comment_space"> <% @comments.each do |c| %> <div class="user_comment"> <a href="/users/<%= @cafe.user_id %>"><%= c.user.email %></a> <%= c.content %> <hr> </div> <% end %> <div class="comment_button"> <%= form_for [@cafe, @comment] do |f| %> <%= f.text_field :content %> <br> <%= f.submit 'コメントする' %> <% end %> </div> </div> <div class="like_space"> <div class="like_number">いいね件数: <%= @cafe.likes.count %></div> <% if current_user.already_liked?(@cafe) %> <%= button_to 'いいねを取り消す', cafe_like_path(@cafe), method: :delete %> <% else %> <%= button_to 'いいね', cafe_likes_path(@cafe) %> <% end %> </div>
class CavesController < ApplicationController before_action :set_cafe, only: [:show, :edit, :update, :destroy] # GET /caves or /caves.json def index @q = Cafe.ransack(params[:q]) @caves = @q.result(distinct: true).page(params[:page]).per(8) end # GET /caves/1 or /caves/1.json def show @cafe = Cafe.find(params[:id]) @comments = @cafe.comments @comment = Comment.new @like = Like.new end # GET /caves/new def new @cafe = Cafe.new end # GET /caves/1/edit def edit end # POST /caves or /caves.json def create @cafe = Cafe.new(cafe_params) @cafe.user_id = current_user.id respond_to do |format| if @cafe.save format.html { redirect_to @cafe, notice: "登録しました" } format.json { render :show, status: :created, location: @cafe } else format.html { render :new, status: :unprocessable_entity } format.json { render json: @cafe.errors, status: :unprocessable_entity } end end end # PATCH/PUT /caves/1 or /caves/1.json def update respond_to do |format| if @cafe.update(cafe_params) format.html { redirect_to @cafe, notice: "更新しました" } format.json { render :show, status: :ok, location: @cafe } else format.html { render :edit, status: :unprocessable_entity } format.json { render json: @cafe.errors, status: :unprocessable_entity } end end end # DELETE /caves/1 or /caves/1.json def destroy @cafe.destroy respond_to do |format| format.html { redirect_to caves_url, notice: "削除しました" } format.json { head :no_content } end end private def set_cafe @cafe = Cafe.find(params[:id]) end def cafe_params params.require(:cafe).permit(:image, :name, :address, :business_hours, :end_business_hours, :number_seats, :wifi, :user_id, :latitude, :longitude, :content) end end
class User < ApplicationRecord has_secure_password has_many :likes has_many :caves, dependent: :destroy has_many :like_caves, through: :likes, source: :cafe has_many :comments VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i.freeze validates :email, { presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } } VALID_PASSWORD_REGEX = /\A[\w\-]+\z/.freeze validates :password, { presence: true, length: { minimum: 8 }, format: { with: VALID_PASSWORD_REGEX }, allow_nil: true } validates :password_confirmation, presence: true def already_liked?(cafe) likes.exists?(cafe_id: cafe.id) end end
require 'rails_helper' RSpec.describe "Caves", type: :request do describe "#new" do let(:cafe) { create(:cafe) } let(:user) { create(:user) } before do session_params = { session: { email: user.email, password: user.password } } post "/login", params: session_params end it 'カフェ登録画面の表示に成功すること' do get '/caves/new' expect(response).to have_http_status(200) end end describe "#create" do let(:cafe) { create(:cafe) } let(:user) { create(:user) } before do session_params = { session: { email: user.email, password: user.password } } post "/login", params: session_params end it 'カフェ作成に成功すること' do valid_params = { image: cafe.image, name: cafe.name, address: cafe.address, number_seats: cafe.number_seats } expect { post '/caves/new', params: { cafe: valid_params } } expect(response).to have_http_status(200) end end describe "#show" do let(:cafe) { create(:cafe) } let(:user) { create(:user) } before do session_params = { session: { email: user.email, password: user.password } } post "/login", params: session_params end it 'カフェ詳細画面の表示に成功すること' do get "/caves/#{cafe.id}" expect(response).to have_http_status(200) end end describe "#edit" do let(:cafe) { create(:cafe) } let(:user) { create(:user) } before do session_params = { session: { email: user.email, password: user.password } } post "/login", params: session_params end it 'カフェ編集画面の表示に成功すること' do get "/caves/#{cafe.id}/edit" expect(response).to have_http_status(200) end end describe "#update" do let(:cafe) { create(:cafe) } let(:user) { create(:user) } before do session_params = { session: { email: user.email, password: user.password } } post "/login", params: session_params end it 'カフェの編集に成功すること' do get "/caves/#{cafe.id}/edit" valid_params = { image: cafe.image, name: cafe.name, address: cafe.address, number_seats: cafe.number_seats } expect { put "/caves/#{cafe.id}", params: { cafe: valid_params } } expect(response).to have_http_status(200) end end end
class ApplicationController < ActionController::Base helper_method :current_user def login? if current_user.nil? redirect_to login_path, alert: "ログインが必要です。" end end def already_login? unless current_user.nil? redirect_to user_path, notice: "ログイン済みです。" end end def current_user if session[:user_id] current_user ||= User.find(session[:user_id]) end current_user end end

試したこと

controllerのshowの箇所に@user = current_user.idの記載をしてみましたが
idがnilにエラーメッセージは変更されました。
gemで'devise'を使用していないことが原因のようにも感じております。

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

ここにより詳細な情報を記載してください。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Ruby on Rails

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