首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails API/Pundit: ActiveModelSerializers的强参数

Rails API/Pundit: ActiveModelSerializers的强参数
EN

Stack Overflow用户
提问于 2019-10-25 21:32:03
回答 1查看 308关注 0票数 0

Pundit部分的This部分说,我们可以控制哪些属性被授权更新。但在使用active_model_seriallizers gem的情况下会失败:

代码语言:javascript
复制
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操作:

代码语言:javascript
复制
def update
  if @post.update(permitted_attributes(@post))
    render jsonapi: @post
  else
    render jsonapi: @post.errors, status: :unprocessable_entity
  end
end

它会失败,并显示错误:

代码语言:javascript
复制
ActionController::ParameterMissing (param is missing or the value is empty: post):
app/controllers/posts_controller.rb:29:in `update'

我还按如下方式创建了PostPolicy

代码语言:javascript
复制
class PostPolicy < ApplicationPolicy
  def permitted_attributes
    if user.admin? || user.national?
      [:title, :body]
    else
      [:body]
    end
  end
end

但它对上述错误没有影响。

你知道我们该怎么做吗?

EN

回答 1

Stack Overflow用户

发布于 2019-10-28 16:41:39

我得到的解决方案(感谢@max提供了一些技巧和技巧)如下:

config/application.rb中添加以下行:

代码语言:javascript
复制
config.action_controller.action_on_unpermitted_parameters = :raise

  1. rescue_from添加到AplicationController或您确切感兴趣的位置:

代码语言:javascript
复制
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操作中的一些属性:)

代码语言:javascript
复制
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

瞧啊。现在,如果不允许的属性将被提交用于update操作,响应将具有500状态并包含ApplicationController#errors_response method中指定的错误。

ATTENTION:如果您在请求中发布了一些关系(例如,您可以将Author作为belongs_to关系与Post一起发布),它仍然会失败。像以前一样使用pundit_params_for将无法提取相应的author_id值。要了解该方法,请参阅我的another帖子,其中我解释了如何使用它。

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58559549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档