【问题标题】:Use Pundit with strong parameters in Rails API在 Rails API 中使用具有强参数的 Pundit
【发布时间】:2019-12-04 16:38:58
【问题描述】:

如果模型包含一些关系,如何在使用 JSON API 时使用 Pundit strong parameters? 我已经posted 提出了一个问题,该问题解释了在单个模型的情况下如何使用它。 儿子,这是可行的:

# posts_controller.rb

def update
    if @post.update(permitted_attributes(@post))
      render jsonapi: @post
    else
      render jsonapi: @post.errors, status: :unprocessable_entity
    end
  end

private

  def set_post
    @post = Post.find(params[:id])
  end

  def post_params
    ActiveModelSerializers::Deserialization.jsonapi_parse(
      params,
      only: [:title, :body, :user]
    )
  end

  def pundit_params_for(_record)
    params.fetch(:data, {}).fetch(:attributes, {})
  end

不幸的是,它将无法提取请求 JSON 的 relationships 块中定义的模型,例如:

"relationships"=>{"country"=>{"data"=>{"type"=>"countries", "id"=>"1"}}, "language"=>{"data"=>{"type"=>"languages", "id"=>"245"}}}

有什么想法吗?

【问题讨论】:

    标签: rails-api pundit


    【解决方案1】:

    我想出了如何让它发挥作用。 在PostsController 中定义的方法pundit_params_for 应该返回ActionController::Parameters 对象并应该使用ActiveModelSerializers::Deserialization.jsonapi_parse! 方法重用post_params 中已经提取的数据:

    # posts_controller.rb
    
    private
    
      def set_post
        @post = Post.find(params[:id])
      end
    
      def post_params
        ActiveModelSerializers::Deserialization.jsonapi_parse!(
          params,
          only: [:body, :framework, :title, :user]
        )
      end
    
      def pundit_params_for(_record)
        ActionController::Parameters.new(post_params)   
      end
    

    所以我必须将post_params 传递给ActionController::Parameters 构造函数。 然后在控制器 update 操作中,您必须使用 Pundit 文档中解释的 permitted_attributes 方法,如下所示:

    # posts_controller.rb
    
    def update
      if @post.update(permitted_attributes(@post))
        render jsonapi: @post
      else
        render jsonapi: @post.errors, status: :unprocessable_entity
      end
    end
    

    至于create action,它没有什么特别之处,只是遵循 Pundit 的文档:

    def create
      @post = Post.new(post_params)
      authorize @post
      if @post.save
        render jsonapi: @post, status: :created, location: @post
      else
        render jsonapi: @post.errors, status: :unprocessable_entity
      end
    end
    

    这里是PostPolicy 的样子:

    # policies/post_policy.rb
    
    class PostPolicy < ApplicationPolicy
      def permitted_attributes
        if user.admin?
          [:title, :body, :framework_id, :user_id]
        else
          [:body]
        end
      end
    
      def create?
        user.admin?
      end
    end
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-07
      • 1970-01-01
      • 2013-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多