The pundit documentation suggests that when using namespaced policies for something like Admin views, it can be useful to override the authorize helper in your AdminController to automatically apply the namespacing:
def authorize(record, query = nil)
super([:admin, record], query)
end
This was working fine when my application was running under ruby 2.7, but is failing under ruby 3.x. It does work as expected if I don't supply a value for query
, but if I try to specify a policy class in my call to authorize
as below, it is ignored.
@licensee = authorize Licensee.find(params[:id]), policy_class: Admin::LicenseePolicy
For the record the Licensee
class uses rails single-table-inheritance (STI), and I am trying to avoid having pundit go looking for non-existent policies for the various subclasses, and just use the "parent" policy class. But in this situation it ignores my policy_class specification and tries/fails to find policies specific to the subclasses.
I figure this relates to ruby 3 changes to hash and keyword argument handling. What is the correct solution to this problem?
The problem can be fixed by explicitly including the policy_class
keyword in the authorize
method override:
def authorize(record, query = nil, policy_class: nil)
super([:admin, record], query, policy_class: policy_class)
end
or, more generally and probably better, using double-splatted keyword arguments:
def authorize(record, query = nil, **kwargs)
super([:admin, record], query, **kwargs)
end