Simple authorization based on controllers and actions
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Build Status

Hadir provides an authorization system like Pundit. With Hadir you separate policy logics and put them in policy classes based on each controller.


All you need is adding hadir to your Gemfile:

gem 'hadir'

Getting Started

Hadir is focused on policy classes. You need a policy class for each controller and a method into it for each action (It's possible to use same method for multiple actions).

In the following controller we prevent to update or delete unpublished post, also in delete action we use custom method and messsage:

class Api::V1::PostsController < ActionController::Base
  def update
    post = Post.find(params[:id])
    authorize post

  def delete
    post = Post.find(params[:id])
    authorize post, 'update?', message: 'You are not allowed to delete unpublished post.'


  def current_user
    # retrieve current-user and return it

Following policy class will allow updating a post if it is not unpublished:

class Api::V1::PostsPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record

  def update?

Hadir makes following assumptions about your policy classes:

  • Policy class name is the same as resource part of controller with Policy suffix.
  • Policy class has the same namespace as contoller class.
  • The first argument is a user. In your controller, Hadir will call the current_user method to retrieve what to send into this class. (null is acceptable)
  • The second argument is an object which you want to check its authorization. It can be any object you want.
  • As a default behaviour Hadir maps your action to the method with the same name and question mark (?) as a suffix. For example Hadir maps update action to update? method in your policy class. It is also possible to send your desired method name as second argument of authorize method.

Hadir vs Pundit - The main differences

In Pundit you create a policy class for each object's class(most of the time a model) and put methods into it for each controller's action, there are some disadvantages:

  • You have only one policy class for different API versions or admin APIs(different controllers) for the same model(class). You will have a messy class!
  • You are not able to have policy if you don't pass a specific object as argument of authorize method.