【发布时间】:2019-10-25 13:32:02
【问题描述】:
This Pundit 部分的部分说我们可以控制哪些属性被授权更新。但是在使用active_model_seriallizers gem 的情况下会失败:
def post_params
# originally geneated by scaffold
#params.require(:post).permit(:title, :body, :user_id)
#To deserialize with active_model_serializers
ActiveModelSerializers::Deserialization.jsonapi_parse!(
params,
only: [:title, :body, :user]
)
end
如果我按照 Pundit 的建议修改 PostsController update 操作:
def update
if @post.update(permitted_attributes(@post))
render jsonapi: @post
else
render jsonapi: @post.errors, status: :unprocessable_entity
end
end
失败并出现错误:
ActionController::ParameterMissing (param is missing or the value is empty: post):
app/controllers/posts_controller.rb:29:in `update'
我还创建了PostPolicy,如下所示:
class PostPolicy < ApplicationPolicy
def permitted_attributes
if user.admin? || user.national?
[:title, :body]
else
[:body]
end
end
end
但对上述错误没有影响。
关于我们如何做到这一点的任何想法?
【问题讨论】:
-
ActionController::ParameterMissing是由ActionController::Parameters.html#require提出的,所以你可能看错了罪魁祸首。 -
我离解决方案越来越近了。我将
pundit_params_for添加到PostsController如下:def pundit_params_for(_record) params.fetch(:data, {}).fetch(:attributes, {}) end,并修改update操作如下:def update if @post.update(permitted_attributes(@post)) render jsonapi: @post else render jsonapi: @post.errors, status: :unprocessable_entity end end。现在,如果用户无权更新title,我会在控制台中看到:Unpermitted parameter: :title。 -
很好,但我会考虑使用
require(:data).require(:attributes)而不是 fetch。如果输入与规范不匹配,您想提前放弃,因为没有继续的意义。 -
您的意思是
fail early而不是bail early吗? -
是的,你说的是番茄……
标签: ruby-on-rails rails-api pundit