Search code examples
ruby-on-railspundit

How to get Pundit to apply a scope to a model with a different name than the policy?


I have a DirectoryController, and -- deliberately -- no UsersController. UsersController will doubtless be added when I create the administration controls, and will have a totally difference scope & purpose.

When I call policy_scoped in the directory controller, I want to use the scope from DirectoryPolicy and not UserPolicy (which doesn't exist yet). I want to do it in a way that verify_policy_scoped recognizes, which means the obvious work around of DirectoryPolicy::Scope.new(current_user, User).resolve is not only a tad long but also actually doesn't work. (Which seems like a bug) This seems like such an obvious oversight that I'm sure there's something, somewhere, to make this work, I just don't know what.

How do I do this in Pundit?


Solution

  • When you do this

    DirectoryPolicy::Scope.new(current_user, User).resolve
    

    you're effectively bypassing pundit's policy_scoped? tracking.

    My first thought is that if DirectoryPolicy::Scope is intended to scope your user data, maybe you need to create a Directory model as pundit expects. It could be as simple as this

    class Directory < User; end
    

    Now when you have something like this in your DirectoryController

    @users = policy_scope(Directory)
    

    pundit can properly infer you want the DirectoryPolicy::Scope, and your resolve method can treat the scope as if it were the User class because of the inheritance.

    If you can't subclass User as I describe here you'll need to show some actual code from your app and provide more context as to what Directory is and what you're trying to do with it.