自分のポートフォリオのアプリケーションに投稿に対して高評価できる機能を実装しようと思ったのですが、投稿が成功して投稿一覧ページに遷移するときにmodelの部分でエラーになってしまいます
ユーザー管理はdeviseを使っています。
参照させていただいた記事はこちらの記事です
↓
Rails いいね機能のミニアプリを作ろう
エラー画面に出てきているコードは、
こちらの部分です
user.rbの部分のコードです
def already_liked?(post) self.likes.exists?(post_id: post.id) end
エラー文は以下の通りです
NoMethodError in Posts#index undefined method `id' for nil:NilClass
#問題のソースコードです
評価機能に関するコントローラー
class LikesController < ApplicationController def create @like = current_user.Likes.create(post_id: params[:post_id]) redirect_back(fallback_location: root_path) end def destroy @like = Like.find_by(post_id: params[:post_id], user_id: current_user.id) @like.destroy redirect_back(fallback_location: root_path) end end
投稿に関するコントローラー
class PostsController < ApplicationController before_action :authenticate_user!, only: [:new, :update, :create, :edit, :update, :destroy] before_action :find_post, only: [:edit, :update, :show, :destroy] def index @posts = Post.all @like = Like.new end def new @post = Post.new @like = Like.new end def show end def create @post = current_user @post = Post.create(post_params) if @post.save redirect_to root_path,notice:'投稿に成功しました' else redirect_to new_post_path,notice:'投稿に失敗しました' end end def edit end def update @post.update(post_params) end def destroy if @post.destroy redirect_to root_path,alert: '投稿を削除しました' else redirect_to root_path end end private def post_params params.require(:post).permit(:content, {images: []}).merge(user_id: current_user.id) end def find_post @post = Post.find(params[:id]) end def force_redirect_unless_my_post return redirect_to root_path,alert:'権限がありません'if @post.user != current_user end end
##ここからは評価機能に関するモデルです
class Like < ApplicationRecord belongs_to :user belongs_to :post validates_uniqueness_of :post_id, scope: :user_id end
以下は投稿に関すモデルです
class Post < ApplicationRecord has_many_attached :images belongs_to :user has_many :likes has_many :liked_users, through: :likes, source: :user validates :content, presence: true end
ユーザーに関するモデルです
class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_one_attached :image has_many :comments has_many :posts has_many :likes, dependent: :destroy has_many :liked_posts, through: :likes, source: :post def already_liked?(post) self.likes.exists?(post_id: post.id) end with_options presence: true do validates :name validates :mania_histry validates :enjoy_point validates :email validates :password, length: { minimum: 6 } end end
##ここからは評価機能をつけたビューです
<div class="content-wrapper"> <div class="content-block"> <% @posts.each do |post| %> <div class="content"> <div class="user-about"> <div class="image"> <% if post.user.image.attached? %> <%= image_tag post.user.image %> <% else %> <%= image_tag no.user.png %> <% end %> </div> <div class="profile"> <div class="name-history"> <div class="name"> <%= post.user.name %> </div> <div class="mania-histry"> <%= "学習歴:#{post.user.mania_histry}年" %> </div> </div> <div class="enjoy-point"> <%= "楽しいポイント#{post.user.enjoy_point}"%> </div> </div> </div> <div class="text"> <p><%= post.content %></p> </div> <% if post.images.attached? %> <% post.images.each do |image| %> <div class = 'images'> <%= image_tag image %> </div> <% end %> <% end %> <div class="action-menu"> <div class="like"> <h3>いいね件数: <%= post.likes.count %></h3> <div class = 'like-button'> <% if current_user.already_liked?(@post) %> <%= button_to 'いいねを取り消す', post_like_path(@post), method: :delete %> <% else %> <%= button_to 'いいね', post_likes_path(@post) %> <% end %> </div> </div> <div class="comment"> </div> </div> </div> <% end %> </div> <div class="sidebar"> <div class="box"> </div> <div class="box"> </div> </div> </div>
試したこと
ビューの部分に
<div class="like"> <h3>いいね件数: <%= post.likes.count %></h3> <div class = 'like-button'> <% if current_user.already_liked?(@post) %> <%= button_to 'いいねを取り消す', post_like_path(@post), method: :delete %> <% else %> <%= button_to 'いいね', post_likes_path(@post) %> <% end %> </div>
こちらの部分を
<div class="like"> <h3>いいね件数: <%= post.likes.count %></h3> <div class = 'like-button'> <%if @post.present?%> <% if current_user.already_liked?(@post) %> <%= button_to 'いいねを取り消す', post_like_path(@post), method: :delete %> <% else %> <%= button_to 'いいね', post_likes_path(@post) %> <% end %> <% end %> </div>
として、postの部分の情報をとってこれるようにしようと思ったのですが、そしたらボタンそのものが表示されなくなってしまいました。
ですのでそれを消したあとに、パスの部分の(@post)の部分を消してみたところ、投稿は表示されたのですが、いいねボタン自体は機能していなかったです。
ですので、やっぱりpost_id :post.id
の部分が機能していないあるいは、postのidをどこかで撮ってこれていないからではないかと考えています。
回答者様にアドバイスを頂いたので、
<%= button_to 'いいねを取り消す', post_like_path(post), method: :delete %> <% else %> <%= button_to 'いいね', post_likes_path(post) %> <% end %>
に変えてみたのですがやはり同じエラーでした。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。