Pundit provides authorization to the application.
Installation
Add this to your Gemfile
gem 'pundit'
bundle
Usage
Pundit is focused around the notion of policy classes. A simple example of how to use policy is as shown below
class UserPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def create?
user.super_admin?
end
end
-
UserPolicy is the class name where User is the model and Policy is suffixed to it. This format should be followed when creating a policy.
-
First argument is the current_user. Pundit calls the current_user method to get the result.
-
Second argument is the model object.
-
Method name in the policy class should be same as controller action. If the method name is not same then you should write in the controller the name as second argument.
How to use pundit in controller
- If controller action is same as policy method
Authorize method automatically starts looking for UserPolicy class and method as create? from action name
class UsersController < ApplicationController
...
def create
@user = User.build(parameters)
authorize @user # Authorizing here
if @user.save
redirect_to users_path
else
render :new
end
end
end
- If controller action is not same as policy method
Authorize method automatically starts looking for UserPolicy class and method as create? because it is passed explicitly
class UsersController < ApplicationController
...
def invite
@user = User.find(params[:id])
authorize @user, :create? # Authorizing here
...
end
end
How to pass additional arguments to policy
Pundit does not allow to pass additional arguments to policy class but in the cases where we have to pass additional arguments, you can use special wrapper class and pass it to policy.
If I have to pass organization_id(field) to policy, I will do as below
class UserContext
attr_reader :user, :organization_id
def initialize(user, organization_id)
@user = user
@organization_id = organization_id
end
end
class ApplicationController
include Pundit
def pundit_user
UserContext.new(current_user, request.organization_id)
end
end
Using that in a policy will be
class ProjectPolicy < ApplicationPolicy
def show?
user.user.admin? && user.user.organization_id == user.organization_id
end
end
Here I am allowing only the user who is admin and is same organization as the organization I am passing in the parameter to see the project page.
Keep Coding !!!
Contact us to work on your website.
- Ameena