Entity-Relationship Diagrams for Ruby on Rails Rails ERD

Browse this page to see some example diagrams. Many of them are generated from actual applications. Want to try for yourself? See the installation instructions. If you have a great example diagram of an open source Rails 3 project that you wish to share, get in touch!

Refinery CMS

Refinery is a content management system for medium-sized websites. The model diagram generated by Rails ERD is particularly clean and convenient.

Refinery CMS entity-relationship diagram

Gemcutter

The Rubygems website is powered by Gemcutter. This application maintains an overview of all available Ruby libraries that are packaged as gems.

Gemcutter entity-relationship diagram

Typo

Some models rely heavily on single table inheritance. Typo, a popular blogging application, uses single table inheritance for many of its most important models. To explicitly display all child models and their relationships, this diagram was generated with inheritance=true.

Typo entity-relationship diagram

Spree

Slightly larger domain models may be difficult to comprehend, even when drawn in a diagram. Spree is an open-source e-commerce application with 60 models. If we hide the attributes, the diagram gives a clearer overview of the entities themselves. This diagram was generated with attributes=false.

Spree entity-relationship diagram

Detailed examples

Now that we've seen some real entity-relationship diagrams, let's see what they're composed of exactly. We start with a single entity. Below is the database migration of a table named photographs, which could contain digital photographs and their metadata. Based on this database table, Rails ERD renders the Photograph entity with all relevant attributes and their types.

ActiveRecord::Schema.define do
  create_table "photographs" do |t|
    t.decimal  :aperture
    t.binary   :data,        :null => false
    t.text     :description,                 :limit => 512
    t.string   :filename,    :null => false, :limit => 64
    t.boolean  :flash
    t.integer  :iso
    t.float    :shutter_speed
    t.datetime :taken_at,    :null => false
  end
end
Example of entity with attributes

Now we take a look at the relationships that are possible in a model diagram. Consider the following two models, which describe countries and their heads of state. They are each associated with the other model, so they share a one-to-one relationship. It is rendered as follows...

class Country < ActiveRecord::Base
  # A country may or may not have a head of state.
  has_one :head_of_state
end


class HeadOfState < ActiveRecord::Base
  belongs_to :country

  # A head of state always belongs to a country.
  validates_presence_of :country
end
One-to-one relationship example

Here's another example. One galleon (a medieval warship) has many cannons. If we model them in a database, they will share a one-to-many relationship. This cardinality is represented with a single arrow.

class Galleon < ActiveRecord::Base
  # Galleons have up to 36 cannons.
  has_many :cannons

  validates_length_of :cannons, :maximum => 36
end


class Cannon < ActiveRecord::Base
  # A cannon belongs to a galleon.
  belongs_to :galleon
end
One-to-many relationship example

When drawing a many-to-many relationship, both ends are represented by an arrow.

# The two models are joined by the join table 'films_genres',
# with two foreign keys, 'film_id' and 'genre_id'.

class Film < ActiveRecord::Base
  # A film belongs to one or more genres.
  has_and_belongs_to_many :genres
end

class Genre < ActiveRecord::Base
  # Each genre may be applicable for one or more films.
  has_and_belongs_to_many :films
end
Many-to-many relationship example

Many-to-many relationships with a join model will be drawn together with this third model. The individual relationships are displayed as one-to-many relationships. The many-to-many relationship is indirect and will be drawn with a dotted line.

class Wizard < ActiveRecord::Base
  has_many :spells, :through => :spell_masteries
  has_many :spell_masteries
end

class Spell < ActiveRecord::Base
  has_many :spell_masteries
end

class SpellMastery < ActiveRecord::Base
  belongs_to :wizard
  belongs_to :spell
end
Indirect many-to-many relationship example

Rails ERD can also draw single table inheritance, often referred to as specialization. Specialized entities are displayed in grey, because they do not have their own table in the database. An open arrow points to their parent entity. Inheritance is not enabled by default, set inheritance=true to turn it on.

class Beverage < ActiveRecord::Base
end

class Beer < Beverage
end

class Whisky < Beverage
end
Single table inheritance example

A slight variation on specialization is generalization. This is achieved when an association is re-used on multiple models, forming polymorphic associations. The generalized entities are fictional, because they are not actual models. They also do not correspond to database tables, so they are displayed in grey. Polymorphism is not enabled by default, set polymorphism=true to turn it on.

class Barricade < ActiveRecord::Base
  # Defensible structures have many soldiers.
  has_many :soldiers, :as => :defensible
end

class Stronghold < ActiveRecord::Base
  # Defensible structures have many soldiers.
  has_many :soldiers, :as => :defensible
end

class Soldier < ActiveRecord::Base
  # Soldiers belong to a defensible structure.
  belongs_to :defensible, :polymorphic => true
end
Single table inheritance example

Alternative notation

Rails ERD's standard notation is designed to be simple. Relationship cardinalities (one-to-many, many-to-many, etc.) are indicated with arrows. But sometimes you also want to know whether a relationship is optional or mandatory. This property of relationships, called participation, can be added to a diagram by using an alternative notation; set with notation=bachman.

The notation that we use was designed by Charles Bachman in 1992. It uses open and closed dots to indicate partial and total participation. Here's an example, a model of fruit orchards...

Orchard entity-relationship diagram

Notice the use of open and closed dots. An open dot means that the relationship to the other entity is optional, seen from the entity it is next to. A closed dot means that the relationship is mandatory. These properties are automatically determined based on your validators and non-nullable foreign keys. Based on the diagram above we can conclude the following...

  • All companies have many orchards; it is required for a company to have orchards (closed dot).
  • Some orchards belong to a company; it is optional for an orchard to belong to a company (open dot).
A company has many orchards
  • Some orchards have one stand; it is optional for an orchard to have a stand (open dot).
  • All stands belong to an orchard; it is mandatory for a stand to belong to an orchard (closed dot).
An orchard has one stand