Skip to main content

Ideal GraphQL Configuration

This guide shows the recommended setup for CM GraphQL using:

In all examples below, replace ModelName with the model where you want this implemented.

1. Define input types for sort​

Use EnumHelper for sort direction and model-specific sortable columns.

module Types
module Inputs
class ModelNameSort < Types::BaseInputObject
graphql_name 'ModelNameSortInput'

argument :column, Types::EnumHelpers.enum_from_array(%w[created_at name],
'ModelNameSortColumn'), required: false
argument :direction, Types::Enums::Base::SortDirection, required: false
end
end
end

2. Define input types for filters​

NOTE: Use Types::Inputs::Base::Filter as the base class for filter inputs, this already have q field for search and ids field for filtering by ids.

module Types
module Inputs
class ModelNameFilter < Types::Inputs::Base::Filter
graphql_name 'ModelNameFilterInput'

argument :some_fields, [String], required: false
end
end
end

3. Define the list query using PagingTypeHelper​

For list queries, use this structure:

module Queries
module ModelName
class List < Queries::BaseQuery
description 'list records on a model'

argument :filters, Types::Inputs::ModelNameFilter, required: false
argument :sort, Types::Inputs::ModelNameSort, required: false
argument :pagination, Types::Inputs::Base::Paging, required: false

type Types::PagingTypeHelper.paging_type_for_model(model: ::ModelName), null: true

def resolve(filters: nil, pagination: nil, sort: nil)
per_page = pagination&.per_page || DEFAULT_PER_PAGE
page = pagination&.page_no || 1
::ModelName.filters(filters).order_by(sort&.column, sort&.direction).list(per_page, page)
end
end
end
end

4. Add the query to your root QueryType​

module Types
class QueryType < Types::BaseObject
field :model_names, resolver: Queries::ModelName::List, description: 'List ModelName records'
end
end

5. On Model this methods and scopes are required​

  • filters class method - for filtering records
  • order_by scope - for sorting records
  • fields filters scopes - for filtering by specific fields

example:

class ModelName < ApplicationRecord
scope :search_filter, lambda { |query|
return all if query.blank?

where('model_names.name ILIKE ?', "%#{query}%")
}

scope :ids_filter, lambda { |ids|
return all if ids.blank?

where(id: ids)
}

scope :order_by, lambda { |column, direction = 'asc'|
return all if column.blank?

order(column => direction)
}

scope :some_fields_filter, lambda { |some_fields|
return all if some_fields.blank?

where(some_field: some_fields)
}

def self.filters(filters)
return all if filters.blank?

all
.search_filter(filters[:q])
.ids_filter(filters[:ids])
.some_fields_filter(filters[:some_fields])
end
end