Scoping is a complementary consideration to authorization. Rather than checking “can this user see this thing?”, scoping takes a list of items filters it to the subset which is appropriate for the current viewer and context. The resulting subset is authorized as normal, and, assuming that it was properly scoped, each item should pass authorization checks.

For similar features, see Pundit scopes and Cancan’s .accessible_by.

scope: option

Fields accept a scope: option to enable (or disable) scoping, for example:

field :products, [Types::Product], scope: true
# Or
field :all_products, [Types::Product], scope: false

For list and connection fields, scope: true is the default. For all other fields, scope: false is the default. You can override this by using the scope: option.

.scope_items(items, ctx) method

Type classes may implement .scope_items(items, ctx). This method is called when a field has scope: true. For example,

field :products, [Types::Product] # has `scope: true` by default

Will call:

class Types::Product < Types::BaseObject
  def self.scope_items(items, context)
    # filter items here

The method should return a new list with only the appropriate items for the current context.