I'm working on a rails app where I wrote a personalized route called "all_designs"; with the corresponding method on the controller and the view, before I add pundit to my project it was working fine.
Now I'm having this error:
Pundit::AuthorizationNotPerformedError in DesignsController#all_designs
I understand that I'm missing a policy for this action, but the way I'm trying is not working.
How can I add a policy for this method?
Controller:
class DesignsController < ApplicationController
before_action :set_design, only: [:show,:edit,:update,:destroy]
def index
@designs = policy_scope(Design.where(user: current_user, status: 'activo'))
@user = current_user
end
def all_designs
@designs = Design.where(user: current_user)
@user = current_user
end
...
end
Policy:
class DesignPolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.all
end
end
def create?
true
end
def show?
true
end
def destroy?
user == record.user
end
def update?
# If the user is the owner of the design
user == record.user
end
def all_designs?
true
end
end
CodePudding user response:
I would consider separate controller and policy for this as what you're doing is really just a nested route (designs belonging to a singleton resource).
scope 'user', module: :users do
resources :designs, only: :index
end
module Users
class DesignsPolicy
class Scope < Scope
def resolve
@user.designs # make sure user has a `has_many :designs` assocation.
end
end
end
def index?
true
end
end
# Represents designs belonging to the current user
module Users
class DesignsController < ApplicationController
# GET /user/designs
def index
@designs = policy_scope
end
end
end
This lets you separate the logic of displaying the the current users designs from /designs
which would display everything in a clean way.
CodePudding user response:
Every method on the controller which needs to be authorized, needs to contains an explicit declaration like this:
def all_designs
@designs = Design.where(user: current_user)
@user = current_user
authorize @designs
end
The reason it wasn't working was: I missed the authorize line