我的创建,更新和政策的政策摧毁"喜欢"要求用户登录。
我的政策措辞如下:
class LikePolicy < ApplicationPolicy
def create?
user && record.user_id == user.id
end
def update?
create?
end
def destroy?
create?
end
end
我喜欢#create controller动作如下:
def create
@article = Article.find(params[:article_id])
@like = @article.likes.new(user_id: current_user.id, value: params[:value] == 1 : 1 ? -1)
authorize(@like)
@like.save
redirect_to @article
end
然而,使用策略来确认用户已登录是不合逻辑的,因为代码将在之前的类似于引用current_user的地方失败。
这是如何授权包含user_id的记录的公认惯例吗?
答案 0 :(得分:3)
通常我会通过单独的身份验证检查来检查用户是否已登录。如果您的应用程序主要要求用户登录,那么在授权之前进行身份验证检查将确保您始终拥有current_user
。
同样对于创建我发现我不喜欢调用new / authorize / save只是为了确保用户正在创建一个属于他们的对象。这是与授权无关的应用程序逻辑。而不是创造,你可以简单地传入课堂,Pundit不介意。
根据您是否先进行身份验证检查,您的授权可以返回true,也可以检查!user.nil
。
我发现Pundit最后一件事就是尝试将逻辑抽象为一些自我记录的方法。它使阅读权威政策更容易,并允许您将逻辑部分抽象到ApplicationPolicy或通过模块包含它们。在下面的示例中,is_owner?
可以很容易地被抽象,因为它可以在许多情况下使用。
示例1:验证然后授权
class LikesController
# Either from devise, or define in ApplicationController
before_action :authenticate_user!
def create
authorize(Like)
article = Article.find(params[:article_id])
article.likes.create(user_id: current_user.id, ...)
redirect_to article
end
end
class LikePolicy < ApplicationPolicy
def create?
true
end
def update?
is_owner?
end
def destroy?
is_owner?
end
private
def is_owner?
user == record.user
end
end
示例2:仅授权
class LikesController
def create
authorize(Like)
article = Article.find(params[:article_id])
article.likes.create(user_id: current_user.id, ...)
redirect_to article
end
end
class LikePolicy < ApplicationPolicy
def create?
!user.nil?
end
def update?
is_owner?
end
def destroy?
is_owner?
end
private
def is_owner?
user && user == record.user
end
end