Rails 4 - Pundit - Create Policy

Rails 6 - Pundit policy wrapper

When calling the authorize method in your controller, you can specify the policy class:

authorize @model, policy_class: ScriptPolicy

I find that this solution generates less boilerplate files.

To authorize a scope:

scenes = policy_scope(Scene, policy_scope_class: ScriptPolicy::Scope)

By the way, this is all covered in pundit's README: https://github.com/varvet/pundit

Create Pundit Policies to API controller methods

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

Rails 4 Pundit - policies in parent models

You can use ProjectPolicy.new(current_user, @project).create? to specific ProjectPolicy.

However, like @miler350 said, @project might be nil. (for example: User has no project created). Make sure your ProjectPolicy#create? handles nil properly.

Rails 4 - Pundit - policies not working

Few things to check because you didn't mention them in your question:

  1. Add include Pundit to the controller

  2. Add authorize [model_instance] in new action and create action

The official https://github.com/elabs/pundit should give you plenty of instruction.

Rails 5 - Pundit policy for the new required model field

You could try to use something like this:

def login_not_authorized
if current_user&.phone.blank?
flash[:alert] = 'You must provide your phone number.'
redirect_to(user_edit_path)
else
flash[:alert] = 'You are not authorized to perform this action.'
redirect_to(request.referer || root_path)
end
end



Related Topics



Leave a reply



Submit