[Ruby] How to automatically generate ER diagram when migrating with Rails 6

2 minute read

Introduction

I have summarized how to automatically generate an ER diagram with Rails 6. In the case of Rails6, Zeitwerk is used by default for autoloading of files, but due to this I was not able to generate ER diagrams well, so I also described a workaround.

Development environment

Rails: 6.0.3 Ruby: 2.7.1 Macbook Pro Graphviz GraphQL (This was due to an auto-generated file.)

ER diagram settings

Install the gem.

Gemfile


group :development do
  gem'rails-erd'
end

Set to gitignore if necessary.

.gitignore


*.dot

You can generate an ER diagram with the command below.

$ bundle exec erd

Automatic generation setting

To automatically generate an ER diagram when migrating, set it in Rakefile. If you don’t need automatic generation, you don’t need to mention it here.

Rakefile


# hook the migrate task
Rake::Task['db:migrate'].enhance do
  if Rails.env.development?
    Rake::Task[:after_migrate].invoke
  end
end

Task after #migrate
task after_migrate: :environment do
  Rake::Task[:create_erd].invoke
end

# Create ER diagram
task create_erd: :environment do
  # attributes=foreign_keys,primary_keys,timestamps (attributes show primary key, foreign key, timestamp)
  # sort=false (do not alphabetize column names)
  # filename=loof-api-server-erd (filename)
  # filetype=dot (file extension)
  sh'bundle exec erd --attributes=foreign_keys,primary_keys,content,timestamps --sort=false --filename=hogehoge --filetype=dot'
end

Error countermeasure

When I stopped using zeitwerk, which autoloads files, and changed to classic, I was able to automatically generate it, but Rspec stopped working.

config/application.rb


config.autoloader = :classic

About zeitwerk’s uninitialized constant XXX (NameError) error [Enable Rails Guide 2 Zeitwerk Mode](https://railsguides.jp/autoloading_and_reloading_constants.html#zeitwerk%E3%83%A2%E3%83%BC%E3%83%89%E3%82%92%(E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B) When not using Rails Guide 11 Zeitwerk

Measures taken

The following error occurred when generating an ER diagram.

terminal


$ bundle exec erd
Failed: Zeitwerk::NameError: expected file /app/graphql/interface_types/base_interface.rb to define constant Types::BaseInterface, but didn't

Apparently the definition method of module is not appropriate. How to break Zeitwerk

It was caused by the file automatically generated by GraphQL, so I changed it as follows.

base_interface.rb


module Types
  module BaseInterface
    include GraphQL::Schema::Interface
    field_class Types::BaseField
  end
end

After measures ↓

base_interface.rb


module Types::BaseInterface
  include GraphQL::Schema::Interface
  field_class Types::BaseField
end

Change other files as well.

base_scalar.rb


module Types
  class BaseScalar <GraphQL::Schema::Scalar
  end
end

After measures ↓

base_scalar.rb


class Types::BaseScalar <GraphQL::Schema::Scalar
end

When the ER diagram was generated again, the following error occurred this time.

terminal


$ bundle exec erd
Failed: RuntimeError: Saving diagram failed!
Verify that Graphviz is installed and in your path, or use filetype=dot.

It is necessary to specify file as dot.

Terminal (specify file)


$ bundle exec erd --filetype=dot

You have now successfully created an ER diagram!

At the end

Since Rails6 x GraphQL was used, the auroload could not be done correctly and it was an error that occurred.