2

How to create Policies for API-Controller's using Pundit gem?

Api controller path: /app/controllers/api/posts_controller.rb

#posts_controller.rb

class Api::PostsController < ApplicationController

  def create
  ......
  end


  def update
  ......
  end

  def delete
  ......
  end

end

I have Controller for the same and the corresponding Model

controller path: /controllers/posts_controller.rb

#posts_controller.rb

class PostsController < ApplicationController

  def create
  ......
  end


  def update
  ......
  end

  def delete
  ......
  end

end

I have created the policies for posts controller. How to create the same for API's Controller

Chetan Datta
  • 447
  • 9
  • 19

1 Answers1

4

Pundit is resource-based, not controller-based. When you call authorize and pass it a resource, Pundit cares about the action name and the resource type, but it does not care about the controller name.

Regardless of whether you call from the Api::PostsController:

# /app/controllers/api/posts_controller.rb

class Api::PostsController < ApplicationController

  def create
    @post = Post.find(params[:post_id])
    authorize @post
  end
end

or from your original PostsController:

# /app/controllers/posts_controller.rb

class PostsController < ApplicationController

  def create
    @post = Post.find(params[:post_id])
    authorize @post
  end
end

So long as @post is a member of the Post class, you can call authorize @post from the controller of a parent or child or a completely unrelated controller, it doesn't matter. In all cases Pundit will go and look for a method called create? within app/policies/post_policy:

# app/policies/post_policy.rb

class PostPolicy < ApplicationPolicy

  attr_reader :user, :post

  def initialize(user, post)
    @user = user
    @post = post
  end

  def create?
    user.present?
  end
end
moveson
  • 5,103
  • 1
  • 15
  • 32