Still they provide
authorized? methods in open-source version but we have to do it manually. You can learn more about field authorization here.
Pundit is a great object oriented authorization for Rails applications. It helps to separate the authorization logic from controllers so that authorization logic can be changed with time according to the current requirements of the system.
In GraphQL rails, we want some fields to only be shown to some specific users rather than all users. Here we will first authorize the field of type if success then will show the value of the field according to type, otherwise
I assume that pundit gem is installed and initialized in your code along with definitely GraphQL.
Let’s take an example that a user has a post, and only the owner of the post can see the number of views on the post. But as we have one post type in graphql so people other than owner have access to that field. So we will be authorizing the field for the owner of the post only.
# app/policies/post_policy.rb class PostPolicy < ApplicationPolicy # only if user is the owner of the post def owner? user.present? && record.user == user end class Scope < Scope def resolve scope.all end end end
Now that we defined the post policy with owner role, we define the post type with number of view field authorization.
# app/graphql/types/post_type.rb module Types class PostType < Types::BaseObject field :id, ID, null: false # .... remaining fields field :number_of_views, Integer, null: true, description: 'number of times user has viewed your post' do def authorized?(object, args, context) Pundit.policy(context[:current_user], object)&.owner? end end # resolvers def number_of_views object.views.count end end end
authorized? returns true or false. So if authorization fails then
nil is shown, otherwise value is shown. So now in future if
owner? definition needs to be changed then it can be done easily. Also we can create the same method name of
number_of_views in pundit policy to restriction flow completely in pundit policy.