Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: scopes on User object for users matching a policy #693

Closed
awh-tokyo opened this issue Nov 4, 2021 · 1 comment
Closed

Question: scopes on User object for users matching a policy #693

awh-tokyo opened this issue Nov 4, 2021 · 1 comment

Comments

@awh-tokyo
Copy link

awh-tokyo commented Nov 4, 2021

Short version of question: How to make scopes on the User object so I can get a collection of Users who have access to a feature, while keeping all the policy stuff in the same place?

More information:

My application has many user classes, only some of whom can be assigned to tickets:

class FeaturesPolicy < Struct.new(:user, :features)
  def dispatch?
    user.has_any_role?(:tenant_internal_field_tech, :tenant_external_field_tech)
  end

This works as expected:

- if policy(:features).dispatch?
  = active_link_to(my_visits_url, {:class => 'sidebar-link', :wrap_tag => :li, :wrap_class => 'sidebar-item', :active => :exclusive}) do
    i.align-middle data-feather="user-check"
    span.align-middle My Scheduled Visits
    span.sidebar-badge.badge.badge-primary = Visit.for_user(current_user).active.count

However, the user does not dispatch himself; an administrator does the dispatches. I would like a collection of User objects who can be dispatched to populate dropdown lists, for example. Currently I have the following, which of course works, but makes way more SQL queries than is necessary:

= f.association :user, :collection => User.ordered.select { |u| FeaturesPolicy.new(u, :features).dispatch? }, :label_method => :full_name

The solution that I don't want is to define a scope on the User model (User.can_dispatch.ordered) because then I'd have to change in two places if I wanted different classes of users to be able to have access to be dispatched.

All of the example scopes in the documentation are about returning records that one particular user has access to. In my case, I would like to return User records that have access to a feature. What is the commonly-accepted pattern for this?

Thank you in advance for any suggestions!

@dgmstuart
Copy link
Collaborator

Unfortunately this is not possible in the general case: the challenge is that methods in policies can contain arbitrary logic involving both the user and the record, and there's no general way to convert arbitrary logic into an ActiveRecord scope which does the same thing in the database.

I feel like you're not alone in raising this question, but we don't recommend any particular approach. See issue #368 for a related discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants