Generating ERDs for large Rails Projects

An Entity Relationship Diagram (ERD) can be a great asset when trying to understand how all the bits of an application are connected. Visualizations of that sort can shorten the time to build a mental model and potentially expose situations that aren’t completely understood.

My favorite gem for generating them for a Rails application is rails-erd. It’s basic usage is simple and it can be configured to run with each migration. One issue I’ve run into though, is that large applications with hundreds of models result in huge ERDs that are unintelligible.

In my experience with large applications it’s usually the case that I don’t need to see the entire web of models all at once, but instead want to gain an understanding of each individual domain.

Running rails-erd from the command line is as simple as:

$ bundle exec erd

Without options this rails-erd will generate an pdf file at in your current directory called erd.pdf.
Like I said, when your app is small this document is extremely helpful and you can probably stop here.

For our use case though, we really want to be able to specify a set of models we want to use for our ERD generation. Rails-erd provides a great configuration option for that called only.

$ bundle exec erd only="Order,Customer,Product"

In this case rails-erd would use the order, customer, and product models to generate the ERD. This is great for one-off situations where you’re trying to get an understanding of a domain that doesn’t already have an ERD generated, but what we really want is to be able to store these groups of models somewhere, so they’re easy to update as changes to our application occur, and can be regenerated to accurately reflect updates to our model.

To solve this problem I created a yaml file to store the models that belong to a each of the domains I’m interested in. Here’s an example:

# lib/tasks/project_erd.yml

erd_diagrams:                 
  shipments:     
    models:     
      - Carriers
      - Trucks
      - Schedules
      - Deliveries
  orders:
    models:      
      - Orders   
      - Customers   
      - Products

In the above example you can see there are two different diagrams we want to generate. One for shipments, and another for orders. Each has a set of models that make up their respective domain and those models should match the class names in our Rails app.

Next, we’ll build a rake task to spin through our yaml file, and call rails-erd with the proper options.

# lib/tasks/project_erds.rake

require "yaml"                                                                  
namespace :project_erds do                
  desc "Generate erd diagrams" 
  task :generate do
    diagrams = YAML.load_file("lib/tasks/project_erd.yml")        
    diagrams["erd_diagrams"].each_pair do |title, models|
      `bundle exec erd --only '#{models["models"].join(",")}' --filename=erds/#{title}`
    end
  end
end

Here we’re parsing our yaml file, and for each domain we have we’re setting the `only` and `filename` options to the set of models and title respectively.

Now, to generate all of our ERDs it’s as simple as running:

$ bundle exec rake project_erds:generate

The task will create a PDF for each domain, and will place all of them in an erds/ directory in the root of your Rails app!

Previous
Previous

Redesigning Our Logo and Color Palette

Next
Next

Using Spacer Templates in Rails