2015-06-24 3 views
0

Когда пользователь пытается нравится комментарий, он сталкивается с этой ошибкой:Как исправить ActiveRecord :: RecordNotFound, когда нравится комментарий?

ActiveRecord::RecordNotFound (Couldn't find Comment with 'id'=3 [WHERE "comments"."user_id" = ?]): 
    app/controllers/comments_controller.rb:58:in `set_comment' 

я держу мастерить с одной из линий в контроллере, но я не уверен, что это ответ.

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 

схемы

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" 

Все остальное работает, как возможность комментировать и как собственный комментарий пользователя, но не тогда, когда пользователь пытается полюбить чужое комментарий.

+0

Это случается только с этим комментарием или со всеми комментариями? –

+0

Это всегда происходит, когда пользователь пытается любить комментарий другого пользователя @ AhmadAl-kheat.Love the profile pic: -] –

+0

У вас есть фильтр, чтобы установить комментарий раньше, чем, а затем вы снова находите комментарий внутри подобного метода, я не знаю, почему вы это делаете. Спасибо;) –

ответ

1

Эта ошибка вызвана

before_action :set_comment, only: [:edit, :update, :destroy, :like] 

Удалить :like решит проблему.

Другие строки кода вашего оригинального сообщения в порядке.

Поскольку Comment который current_user любит НЕ ПРИНАДЛЕЖИТ current_user, current_user.comments.find(params[:id])ActiveRecord::RecordNotFound поднимет.

1

Согласно документации here исключение ActiveRecord::RecordNotFound будет выбрано, если запись не будет найдена.

В сообщении об ошибке указано app/controllers/comments_controller.rb:58:in 'set_comment'. set_comment кажется, вызывался, потому что вы сообщите своему контроллеру назвать это как before_action

before_action :set_comment, only: [:edit, :update, :destroy, :like]

set_comment выполняет следующие

@comment = current_user.comments.find(params[:id])

Это только глядя в сферу действия current_user-х комментарии, которые объясняют, почему пользователю могут нравиться его собственные комментарии, но не чьи-либо еще. Вы должны изменить его

@comment = Comment.find(params[:id])

Теперь он будет искать все комментарии с этим идентификатором. Кроме того, это означает, что вы можете удалить первую строку действия like, так как она делает то же самое, что и set_comment, что является избыточным (вы дважды запрашиваете свой db).

+0

Это не похоже на работу Adib, потому что теперь, когда я пытаюсь понравиться комментарий, я получаю ошибка, «Два много нравится» по какой-то причине. Поэтому я думаю, что ответ Aetherus может быть лучшим, если я не сделаю что-то неправильно здесь, и в этом случае ваш ответ будет лучше, так как его еще одна строка кода:] –

+0

Вы не должны упускать сообщения об ошибках, менять ответы SO и не понимать что делает ваш код. Причина, по которой вы получаете это, заключается в том, что '@ comment_like.save' не удалось сохранить, что, вероятно, связано с тем, что' @ comment_like.valid? 'Является ложным (это недопустимая запись). Перед тем, как сохранить комментарий_like, напечатайте '@ comment_like.errors' на консоли, чтобы получить список ошибок. – Adib

+1

@Adib, если он делает то, что вы предлагаете, другие методы будут ломаться, потому что он структурировал свой код таким образом, который зависит от нахождения комментария current_user, чтобы он мог редактировать/обновлять/уничтожать его. Поэтому я не рекомендую этот путь в этом случае. Но вы правы, так должно быть сделано в идеальном мире. –

Смежные вопросы