Ideal GraphQL Configuration
This guide shows the recommended setup for CM GraphQL using:
- EnumHelper for reusable enum types in sort inputs and filters
- PagingTypeHelper for standardized list response types
In all examples below, replace
ModelNamewith 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â
filtersclass method - for filtering recordsorder_byscope - 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