[英]How to allow users to delete or update non-user resources and only there own?
Non-users in my application cannot delete or update comments by a user and users only can update or delete there own comments or a non-users comments. 我的应用程序中的非用户无法删除或更新用户的评论,而用户只能更新或删除自己的评论或非用户的评论。 The problem I'm having is writing this correctly and safely.
我遇到的问题是正确,安全地编写此代码。
This is how I create a new comment and this works without access to the user_id but I'm not sure what to do with the update and delete methods. 这是我创建新注释的方式,并且可以在不访问user_id的情况下运行,但是我不确定如何处理update和delete方法。 Right now they just allow the current user to delete or update comments
目前,他们只允许当前用户删除或更新评论
CommentsController 评论控制器
def new
@post = Post.find(params[:post_id])
@comment = Comment.new
end
def edit
@post = Post.find(params[:post_id])
@comment = Comment.find(params[:id])
end
def create
@post = Post.find(params[:post_id])
if signed_in?
@comment = current_user.comments.build(comment_params)
else
@comment = Comment.create(comment_params)
end
if @comment.save.....
end
def update
@post = Post.find(params[:post_id])
@comment = current_user.comments.find(params[:id])
if @comment.update(comment_params)..........
end
def destroy
@comment = current_user.comments.find(params[:id])
@comment.destroy
end
private
def comment_params
params.require(:comment).permit(:body, :post_id)
end
I think have to some how get to the @comment.user field but how would I do that if I have to find the comment first? 我认为一定要如何到达@ comment.user字段,但是如果必须先找到评论,该怎么办? Or, how would this be done if that isn't the right way?
或者,如果这不是正确的方法,该怎么办?
Answer 回答
This is what I ended up doing: 这就是我最终要做的事情:
def update
@post = Post.find(params[:post_id])
@comment = Comment.find(params[:id])
if @comment.user == current_user
if @comment.update(comment_params)
redirect_to @comment
else
render action: 'edit'
end
elsif @comment.user.blank?
if @comment.update(comment_params)
redirect_to @comment
else
render action: 'edit'
end
else
redirect_to @comment, notice: "An Error occured"
end
end
Assuming that comments created by guest users have user_id
field set to nil, you can do something like 假设来宾用户创建的评论的
user_id
字段设置为nil,则可以执行以下操作
class Post < ActiveRecord::Base
...
scope :comments_editable_by, ->(user_id) { where('user_id is null or user_id = ?', user_id) }
...
end
And use this scope instead of comments
in the update
and destroy
actions. 并在
update
和destroy
操作中使用此作用域代替comments
。
I think your best bet is to use an authorization system such as declarative_authorization
, pundit
, or cancancan
. 我认为最好的方法是使用一个授权系统,如
declarative_authorization
, pundit
或cancancan
。 They also provide view helpers that will let you hide the update link from users that can't update a particular comment. 它们还提供了视图帮助器,可让您向无法更新特定评论的用户隐藏更新链接。
Although if this is the only place you want authorization then writing your own solution as you suggest is probably a better option. 尽管如果这是您唯一需要授权的地方,那么按照您的建议编写自己的解决方案可能是一个更好的选择。 You could do something like this:
您可以执行以下操作:
def CommentsController < ApplicationController
...
def update
@comment.update comment_params
if @comment.authorized_update!(current_user)
redirect_to @comment, status: :accepted
else
redirect_to @comment, status: :unauthorized
end
end
end
Then in your model: 然后在您的模型中:
def Comment < ActiveRecord::Base
...
def authorized_update!(current_user)
if user == current_user
self.save
else
errors[:base] << "Unauthorized"
false
end
end
end
You'll probably have to tweak it to fit your needs, but you get the idea. 您可能必须对其进行调整以满足您的需求,但是您明白了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.