Created
December 17, 2021 14:31
-
-
Save rmosolgo/cf739704b38cdfc1559dc12a576bf2c4 to your computer and use it in GitHub Desktop.
List scoping with GraphQL-Pro Pundit integration
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
require "bundler/inline" | |
gemfile do | |
gem "graphql", "1.13.1" | |
gem "graphql-pro" | |
end | |
class Schema < GraphQL::Schema | |
class BaseObject < GraphQL::Schema::Object | |
include GraphQL::Pro::PunditIntegration::ObjectIntegration | |
end | |
class ThingPolicy | |
class Scope | |
def initialize(current_user, scope) | |
@current_user = current_user | |
@scope = scope | |
end | |
def resolve | |
if @current_user.admin? | |
@scope | |
else | |
@scope.select { |t| !t[:secret] } | |
end | |
end | |
end | |
end | |
class Thing < BaseObject | |
pundit_policy_class ThingPolicy | |
pundit_role nil | |
field :name, String | |
end | |
class Query < BaseObject | |
pundit_role nil | |
field :things, [Thing] | |
def things | |
# This uses a `Set` just because Pundit doesn't work well with Arrays | |
# (https://github.com/rmosolgo/graphql-ruby/issues/2008) | |
# In practice, it's assumed that this would be an ActiveRecord::Relation or similar list object. | |
Set.new([ | |
{ name: "Wizard Hat", secret: false }, | |
{ name: "Wizard Staff", secret: false }, | |
{ name: "Magic Potion", secret: true }, | |
]) | |
end | |
end | |
query(Query) | |
end | |
query_string = "{ things { name } }" | |
# Run the query with `admin?: true`: | |
pp Schema.execute( | |
query_string, | |
context: { current_user: OpenStruct.new(admin?: true)} | |
).to_h | |
# All items are visible: | |
# | |
# {"data"=> | |
# {"things"=> | |
# [{"name"=>"Wizard Hat"}, | |
# {"name"=>"Wizard Staff"}, | |
# {"name"=>"Magic Potion"}]}} | |
# Run the query with `admin?: false`: | |
pp Schema.execute( | |
query_string, | |
context: { current_user: OpenStruct.new(admin?: false)} | |
).to_h | |
# One item is removed: | |
# | |
# {"data"=> | |
# {"things"=> | |
# [{"name"=>"Wizard Hat"}, | |
# {"name"=>"Wizard Staff"}]}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment