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
但是对以上错误没有影响。关于我们如何做到这一点的任何想法?
config/application.rb
:config.action_controller.action_on_unpermitted_parameters = :raise
将
rescue_from
添加到AplicationController
或您确切感兴趣的位置:
class ApplicationController < ActionController::API
include ActionController::MimeResponds
include Pundit
rescue_from Pundit::NotAuthorizedError, ActionController::UnpermittedParameters, with: :user_not_authorized
...
private
def user_not_authorized
render jsonapi: errors_response, status: :unathorized
end
def errors_response
{
errors:
[
{ message: 'You are not authorized to perform this action.' }
]
}
end
end
然后将pundit_params_for
方法添加到PostsController
并更改update
操作(就我而言,我只想限制update
操作中的某些属性:)
class PostsController < ApplicationController ... def update if @post.update(permitted_attributes(@post)) render jsonapi: @post else render jsonapi: @post.errors, status: :unprocessable_entity end end private def post_params ActiveModelSerializers::Deserialization.jsonapi_parse!( params, only: [:title, :body, :user] ) end def pundit_params_for(_record) params.fetch(:data, {}).fetch(:attributes, {}) end end
Voilà。现在,如果将为update
操作提交不允许的属性,则响应将具有500
状态,并包含ApplicationController#errors_response method
中指定的错误。希望这会有所帮助。