Punditry
A super-slim wrapper on top of Pundit.
Installation
Add this line to your application's Gemfile:
gem 'punditry'
And then execute:
$ bundle
Include Punditry in your application controller:
class ApplicationController < ActionController::Base
include Punditry::Controller
endUsage
Punditry is essentially Pundit with a few minor additions. Instead of calling authorize, you call authorize!. This delegates to authorize underneath but will also return the passed in resource, allowing you to eliminate a line of code:
# with Pundit
def update
@post = Post.find(params[:id])
authorize @post
if @post.update(post_params)
redirect_to @post
else
render :edit
end
end# with Punditry
def update
@post = authorize!(Post.find(params[:id]))
if @post.update(post_params)
redirect_to @post
else
render :edit
end
endWoohoo! Big win! I also prefer the bang method to indicate that it raises an error when it is not authorized, but that's a matter of taste.
authorize! has one more addition. If you pass in a collection, it also calls policy_scope on the resource. This makes the assumption that you want to authorize index actions as well, instead of only scoping them. This is another matter of taste. Also, reflecting this assumption, Punditry verifies that every action calls authorize! including index. If you need to opt out of this, you can simply call skip_authorization in your controller:
class PostsController < ApplicationController
skip_authorization only: :check
def check
# some action that does not require authorization
end
endPunditry::Controller gives you one other helper method. If you follow the recommendations here, then you can simply pass a resource to whitelist and get back the permitted attributes for that resource:
def update
@post = authorize!(Post.find(params[:id]))
if @post.update(whitelist(@post))
redirect_to @post
else
render :edit
end
endPunditry also provides you with a base policy Punditry::Policy that all of your polices should inherit from. This policy is very basic, but using it allows you to write tests like this. Simply require punditry/rspec in your spec_helper/rails_helper.
That's it. Punditry simply leverages the power and simplicity of Pundit while making things just slightly more convenient.