我正在使用设计进行用户身份验证。 并有三个模型,文章,评论和用户。
我只能让登录用户向文章添加评论。我还有注释在注释表中添加用户 ID。 但是,我正在努力实现仅限制评论作者删除自己的评论的功能。
我有什么:
评论.rb
class Comment < ApplicationRecord
belongs_to :user
belongs_to :article
end
用户.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
has_many :comments
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
文章.rb
class Article < ApplicationRecord
has_many :comments, dependent: :destroy
end
Comments_controller
class CommentsController < ApplicationController
before_action :authenticate_user!
before_action :find_comment, only: [:create, :destroy]
before_action :comment_auth, only: [:edit, :update, :destroy]
#Some items removed for brevity
def destroy
@comment = @article.comments.find(params[:id]).destroy
redirect_to article_path(@article)
end
private
def comment_params
params.require(:comment).permit(:name, :body, :user_id)
end
def find_comment
@article = Article.find(params[:article_id])
end
def comment_auth
if @comment.user_id != current_user.id
flash[:notice] = 'You are not owner of this comment.'
redirect_to(root_path)
end
end
我还在注释表上添加了一个外键:
class AddForeignKeys < ActiveRecord::Migration[5.0]
def change
add_foreign_key :comments, :users
end
end
然后,当尝试从我创建并登录的用户中删除评论时,我得到:
NoMethodError in CommentsController#destroy
undefined method `user_id' for nil:NilClass
我错过了什么?
问题
这是在过滤器之前,@comment
尚未初始化。 @comment
在destroy
操作中不可用before_filter
def comment_auth
if @comment.user_id != current_user.id
flash[:notice] = 'You are not owner of this comment.'
redirect_to(root_path)
end
end
解决方案:您可以删除comment_auth
并将操作destroy
更改为:
def destroy
@comment =
current_user.comments.find_by(id: params[:id], article_id: @article)
if @comment && @comment.destroy
redirect_to article_path(@article), notice: 'comment deleted successfully'
else
redirect_to article_path(@article), alert: 'something went wrong'
end
end
或comment_auth
更改为
def comment_auth
@comment =
current_user.comments.find_by(id: params[:id], article_id: @article)
if @comment.user_id != current_user.id
flash[:notice] = 'You are not owner of this comment.'
redirect_to(root_path)
end
end
# AND
def destroy
if @comment.destroy
redirect_to article_path(@article), notice: 'comment deleted successfully'
else
redirect_to article_path(@article), alert: 'something went wrong'
end
end
注意:另外,如果
comment.user_id == current_user.id
,我建议仅在评论中显示删除选项
@comment = find_comment
添加到您的comment_auth
方法中将解决您的问题。
def comment_auth
@comment = find_comment
if @comment.user_id != current_user.id
flash[:notice] = 'You are not owner of this comment.'
redirect_to(root_path)
end
end