Reputation: 2866
When a user tries to like a comment he is confronted with this error:
ActiveRecord::RecordNotFound (Couldn't find Comment with 'id'=3 [WHERE "comments"."user_id" = ?]):
app/controllers/comments_controller.rb:58:in `set_comment'
I keep tinkering with one of the lines in the controller, but I'm not sure if that's the answer.
comments_controller
class CommentsController < ApplicationController
before_action :set_commentable, only: [:index, :new, :create]
before_action :set_comment, only: [:edit, :update, :destroy, :like]
before_action :correct_user, only: [:edit, :update, :destroy]
def index
@comments = @commentable.comments
end
def new
@comment = @commentable.comments.new
end
def create
@comment = @commentable.comments.new(comment_params)
if @comment.save
redirect_to @commentable, notice: "Comment created."
else
render :new
end
end
def edit
end
def update
if @comment.update_attributes(comment_params)
redirect_to :back, notice: "Comment was updated."
else
render :edit
end
end
def destroy
@comment.destroy
redirect_to @comment.commentable, notice: "Comment destroyed."
end
def like
@comment = Comment.find(params[:id]) # I've been tinkering with this line.
@comment_like = current_user.comment_likes.build(comment: @comment)
if @comment_like.save
@comment.increment!(:likes)
flash[:success] = 'Thanks for liking!'
else
flash[:error] = 'Too many likes'
end
redirect_to(:back)
end
private
def set_commentable
@commentable = find_commentable
end
def set_comment
@comment = current_user.comments.find(params[:id])
end
def correct_user
@comment = current_user.comments.find_by(id: params[:id])
redirect_to root_url, notice: "Not authorized to edit this comment" if @comment.nil?
end
def find_commentable
if params[:goal_id]
Goal.find(params[:goal_id])
elsif params[:habit_id]
Habit.find(params[:habit_id])
elsif params[:valuation_id]
Valuation.find(params[:valuation_id])
elsif params[:stat_id]
Stat.find(params[:stat_id])
end
end
def comment_params
params[:comment][:user_id] = current_user.id
params.require(:comment).permit(:content, :commentable, :user_id, :like)
end
end
comment_like.rb
class CommentLike < ActiveRecord::Base
belongs_to :user
belongs_to :comment
belongs_to :habit
belongs_to :stat
belongs_to :valuation
belongs_to :goal
validates :user, uniqueness: { scope: :comment }
belongs_to :liker, class_name: 'User', foreign_key: :user_id
belongs_to :liked_comment, class_name: 'Comment', foreign_key: :comment_id
end
comment.rb
class Comment < ActiveRecord::Base
after_save :create_notification
has_many :notifications
has_many :comment_likes
has_many :likers, through: :comment_likes, class_name: 'User', source: :liker
belongs_to :habit
belongs_to :stat
belongs_to :valuation
belongs_to :goal
belongs_to :user
validates :user, presence: true
private
def create_notification
author =
if goal
goal.user
#elsif comment_like
# comment_like.user
elsif habit
habit.user
elsif stat
stat.user
elsif valuation
valuation.user
end
notifications.create(
comment: self,
likes: likes,
habit: habit,
stat: stat,
goal: goal,
valuation: valuation,
user: author,
read: false
)
end
end
schema
create_table "comment_likes", force: true do |t|
t.integer "user_id"
t.integer "comment_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "comments", force: true do |t|
t.text "content"
t.integer "goal_id"
t.integer "habit_id"
t.integer "valuation_id"
t.integer "stat_id"
t.integer "commentable_id"
t.string "commentable_type"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "likes"
end
add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type"
add_index "comments", ["commentable_type", "commentable_id"], name: "index_comments_on_commentable_type_and_commentable_id"
add_index "comments", ["user_id"], name: "index_comments_on_user_id"
Everything else works, like the ability to comment and like a user's own comment, but not when a user tries to like someone else's comment.
Upvotes: 0
Views: 66
Reputation: 8898
This error is caused by
before_action :set_comment, only: [:edit, :update, :destroy, :like]
Remove :like
will solve the issue.
Other lines of code of your original post are fine.
Because the Comment
which current_user
likes DOES NOT BELONG TO current_user
, current_user.comments.find(params[:id])
will raise ActiveRecord::RecordNotFound
.
Upvotes: 1
Reputation: 572
As per the documentation here, an ActiveRecord::RecordNotFound
exception will be thrown if the record is not found.
The error message states app/controllers/comments_controller.rb:58:in 'set_comment'
. set_comment
seems to be getting called because you tell your controller to call it as a before_action
before_action :set_comment, only: [:edit, :update, :destroy, :like]
set_comment
does the following
@comment = current_user.comments.find(params[:id])
It's only looking within the scope of the current_user
's comments, which explains why a user can like his own comments but not anyone else's. You need to change it to
@comment = Comment.find(params[:id])
Now it'll look for all comments with that id. Also, this means you can remove the first line of the like
action since it does the same thing as set_comment
which is redundant (you're querying your db twice).
Upvotes: 1