Hadir

Ali Sepehri
salamcinema
Published in
2 min readJan 17, 2018

--

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

Installation

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
end

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

private

def current_user
# retrieve current-user and return it
end
end

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
end

def update?
record.published?
end
end

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

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 metho

--

--