Pundit policies with two input parameters
Relying on more than the current user and a domain model is a code smell, but in case it really is required, then you can use a custom query method with any number of parameters and raise an exception if the requirements don't met:
class BarPolicy < ApplicationPolicy
def authorize_test?(foo)
raise Pundit::NotAuthorizedError, "not authorized to test" unless record.foo_id == foo
end
end
class BarsController < ApplicationController
def test
skip_authorization && BarPolicy.new(current_user, @record).authorize_test?(@foo)
...
end
end
The skip_authorization &&
part is not required if after_action :verify_authorized
is not used, I just wanted to show a one-liner that can be used in this case to get rid of the not-authorized exception while still having the requirement to authorize the action.
I found the answer at here.
Here is my way:
Add a pundit_user
function in ApplicationController
:
class ApplicationController < ActionController::Base
include Pundit
def pundit_user
CurrentContext.new(current_user, foo)
end
Create the CurrentContext
class:
/lib/pundit/current_context.rb
class CurrentContext
attr_reader :user, :foo
def initialize(user, foo)
@user = user
@foo = foo
end
end
Update the initialize Pundit method.
class ApplicationPolicy
attr_reader :user, :record, :foo
def initialize(context, record)
@user = context.user
@foo = context.foo
@record = record
end
end