-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1723 from rmosolgo/list-scoping
Add .scope_items for filtering lists
- Loading branch information
Showing
7 changed files
with
285 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
--- | ||
layout: guide | ||
search: true | ||
section: Authorization | ||
title: Scoping | ||
desc: Filter lists to match the current viewer and context | ||
index: 4 | ||
--- | ||
|
||
|
||
_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](https://github.com/varvet/pundit#scopes) and [Cancan's `.accessible_by`](https://github.com/cancancommunity/cancancan/wiki/Fetching-Records). | ||
|
||
## `scope:` option | ||
|
||
Fields accept a `scope:` option to enable (or disable) scoping, for example: | ||
|
||
```ruby | ||
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, | ||
|
||
```ruby | ||
field :products, [Types::Product] # has `scope: true` by default | ||
``` | ||
|
||
Will call: | ||
|
||
```ruby | ||
class Types::Product < Types::BaseObject | ||
def self.scope_items(items, context) | ||
# filter items here | ||
end | ||
end | ||
``` | ||
|
||
The method should return a new list with only the appropriate items for the current `context`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# frozen_string_literal: true | ||
|
||
module GraphQL | ||
class Schema | ||
class Member | ||
module Scoped | ||
# This is called when a field has `scope: true`. | ||
# The field's return type class receives this call. | ||
# | ||
# By default, it's a no-op. Override it to scope your objects. | ||
# | ||
# @param items [Object] Some list-like object (eg, Array, ActiveRecord::Relation) | ||
# @param context [GraphQL::Query::Context] | ||
# @return [Object] Another list-like object, scoped to the current context | ||
def scope_items(items, context) | ||
items | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.