Ruby Open Source: Zammad example

Ruby Open Source: Zammad example

Another example of an open source web app written in Ruby

I will probably start a series of open-source Ruby Projects. Maybe I will call it #opensource #Friday.

Zammad is an open-source ticketing system, that also offers an on-cloud product.

They have their product open-sourced on Github and it is built using (at the moment of writing this article) Ruby 3.1.3 and Rails 7


The license is GNU AGPL

They mention on their website why they chose to make the product open source:

Each file in the repository has a license line like:

Some ideas from the open-source repo

I don't have enough time to analyse in depth the repo. So just looking around for 30 minutes, here are some things that I extracted


Running rails stats returned the following:

Result of executing rails stats on the repo

Styling Guide

They use Rubocop with extra cops added. They require some cops provided by gems and custom cops written by them:

  - rubocop-capybara
  - rubocop-factory_bot
  - rubocop-faker
  - rubocop-graphql
  - rubocop-inflector
  - rubocop-performance
  - rubocop-rails
  - rubocop-rspec
  - ../config/initializers/inflections.rb
  - ./rubocop_zammad.rb

In rubocop_zammad.rb they are loading custom cops from .rubocop/cop/zammad

Here are some custom cops written by them:

  • Checking if the migration file starts with a valid timestamp

  • Checking usages of find_by to check if an Active Record exists and replace it with exists?

  • Checking that the only allowed default_scope is about simple ordering

  • Checking for using rand

  • Checking usages of .to_sym on strings and change to : prefix

  • Checking usages of unless and suggest using !

  • Checking copyright notice and adding it when missing

More about their style guide can be found at doc/developer_manual/standards


They appear to use 3 DBs, each one having their group. One (the activerecord-nulldb-adapter) is actually a NullObject pattern implemented for Active Record.

Based on the loaded connection they do a preflight check in an initializer. This is what it looks like:

Rails.application.config.after_initialize do

and you can go check lib/zammad/application/initializer to see what kind of checks are executed for each adapter.

This is a way to make sure that the actual DB server respects a contract they have defined in these initializers (e.g. what extensions are activated or config defaults or minimum version).

See this example of a check for MySQL from the same file:

Code sample from MySQL DB preflight check

Some gems used

  • argon2 - "A Ruby gem offering bindings for Argon2 password hashing"

  • rszr - "Rszr is an image resizer for Ruby based on the Imlib2 library. It is faster and consumes less memory than MiniMagick, GD2 and VIPS, and comes with an optional drop-in interface for Rails ActiveStorage image processing"

  • biz - "Time calculations using business hours"

  • diffy - "It provides a convenient way to generate a diff from two strings or files. Instead of reimplementing the LCS diff algorithm Diffy uses battle tested Unix diff to generate diffs, and focuses on providing a convenient interface, and getting out of your way"

  • chunky_png - "ChunkyPNG is a pure Ruby library to read and write PNG images and access textual metadata. It has no dependency on RMagick, or any other library for that matter"

  • localhost - "This gem provides a convenient API for generating per-user self-signed root certificates"

  • activerecord-nulldb - "NullDB is the Null Object pattern as applied to ActiveRecord database adapters. It is a database backend that translates database interactions into no-ops. Using NullDB enables you to test your model business logic - including after_save hooks - without ever touching a real database"

Design Patterns

They use service objects. There is a Service::Base class that is empty and then there is also Service::BaseWithCurrentUser that looks something like this:

The main method that a Service object should define is execute but there is no enforcement of this. It is just that everything under app/services/service has this method defined.

GraphQL objects

All the logic about GraphQL is inside app/graphql, namescoped to Gql.


They can be found at app/jobs. Job priority is defined in a concern called ApplicationJob::HasQueuingPriority that looks like this:

And all jobs have a default priority of 200 while low_priority is defined as being 300


They are under app/models and there is an ApplicationModel defined that includes some defaults like this:

There are probably a lot more interesting things to discover about the codebase but this is what I got in a short review.

Enjoyed this article?

Join my Short Ruby News newsletter for weekly Ruby updates from the community. For more Ruby learning resources, visit You can also find me on or Linkedin or Twitter.

Did you find this article valuable?

Support Lucian Ghinda by becoming a sponsor. Any amount is appreciated!