Skip to content

Quail

Define a resource. Get a full GraphQL API. Convention-over-configuration for Rails developers who want GraphQL without the boilerplate.

Convention over Configuration

Define a resource class with a simple DSL and Quail auto-generates GraphQL types, queries, mutations, and subscriptions from your ActiveRecord models.

Turbo streamed GraphQL Subscriptions

Declare subscribe_on in a resource and Quail wires up GraphQL subscriptions powered by Rails ActionCable.

Rails-native Tooling

Generators, rake tasks, Railtie integration, and patterns that feel like home. Your models stay clean; the GraphQL layer lives in its own space.

AGENTS.md Ready

Documentation ships with llms.txt support, making it easy for AI coding agents to read and understand Quail without any extra effort.


  1. Install Quail and scaffold your GraphQL layer

    Terminal window
    rails generate quail:install

    This creates:

    app/
    ├── channels/
    │ └── graphql_channel.rb # ActionCable for subscriptions
    ├── controllers/
    │ └── graphql_controller.rb # Ready-to-go controller
    └── graphql/
    ├── app_schema.rb # Your GraphQL schema
    ├── mutations/ # Custom mutation classes
    ├── queries/ # Custom query resolvers
    ├── resources/ # Where your resource files live
    ├── subscriptions/ # Custom subscription classes
    └── types/ # Custom GraphQL types
    config/
    └── initializers/
    └── quail.rb # Configuration
  2. Create a model and generate its resource

    Terminal window
    rails g model Article title:string body:text published_at:datetime author:references
    rails db:migrate
    rails generate quail:resource Article
  3. Define what to expose in the resource

    app/graphql/resources/article_resource.rb
    class ArticleResource
    include Quail::Resource # Activates the DSL and registers this resource
    # Expose these columns as GraphQL fields
    attributes :id, :title, :body, :published_at
    # Wire up associations — types resolve automatically
    has_many :comments
    belongs_to :author
    # Only these fields are accepted in create/update mutations
    writable_attributes :title, :body
    # Push real-time updates over ActionCable
    subscribe_on :create, :update
    end
  4. Dump the schema to see what Quail generated

    Terminal window
    rails quail:dump
type Article {
id: ID!
title: String!
body: String!
publishedAt: ISO8601DateTime
comments: [Comment!]!
author: Author!
}
type ArticleConnection {
edges: [ArticleEdge!]!
nodes: [Article!]!
pageInfo: PageInfo!
}
type Query {
article(id: ID!): Article
articles(first: Int, after: String, last: Int, before: String): ArticleConnection!
}
type Mutation {
articleCreate(input: ArticleCreateInput!): Article
articleUpdate(input: ArticleUpdateInput!): Article
articleDelete(input: ArticleDeleteInput!): Article
}
type Subscription {
articleCreated: Article!
articleUpdated: Article!
}

One resource file. Full CRUD, pagination, and real-time subscriptions — no boilerplate.

Dive into the Quick Start →