rails-erd icon indicating copy to clipboard operation
rails-erd copied to clipboard

Rails 6 support ?

Open 3pns opened this issue 5 years ago • 23 comments

On the same Mac OS laptop:

  • it works on an old rails 5 project
  • on a new rails 6 project it only detects 2 model amongst my 6 model, one of them being ApplicationRecord, I don't understand why as they were all generated with rails g model my_model. Is anybody else able to generate the erd pdf on a rails 6 project ?
Loading application environment...
Loading code in search of Active Record models...
Generating Entity-Relationship Diagram for 2 models...
Warning: Ignoring invalid association :server_user on User (model ServerUser exists, but is not included in domain)
Warning: Ignoring invalid association :servers on User (model Server exists, but is not included in domain)
Done! Saved diagram to erd.pdf.

3pns avatar May 08 '19 11:05 3pns

@3pns I also had problems to generate a diagram after I added active storage to my application. (before that it worked with rails 6 beta?!)

I got it working when I add

Zeitwerk::Loader.eager_load_all

to my config/environment.rb after the rails initialization.

The rake task to generate the diagram calls Rails.application.eager_load! which seems to be not enough for Rails 6, because of the migration to Zeitwerk? It also works as expected when I replace the eager load call there to zeitwerk. Maybe @kerrizor can explain that better. :)

Sadly I have no time to figure this out, but maybe the workaround helps.

DonSchado avatar May 09 '19 12:05 DonSchado

Thank you very much @DonSchado it does works ! I added a conditional not to impact how the app is run in environments other than development.

if Rails.env.development?
  Zeitwerk::Loader.eager_load_all
end

3pns avatar May 09 '19 13:05 3pns

Be careful... even if this works for rails-erd, when you also use StatefulEnum by @amatsuda this will fail silently and skip the generation of the state machine diagram 😕

Super confusing...

edit: one reasonable addition to your conditional might then be something like

ARGV.include?('erd')

DonSchado avatar May 09 '19 13:05 DonSchado

The change to Zeitwerk appears to have been rolled back, but a number of changes to the internals broke testing for a few weeks; I got Rails 6.0.0.rc1 working today (I think) in #329 and it will roll out in the v1.6.0 release in the next few hours. If you have a Rails 6 app, I would love additional feedback and :eyes: to make sure this works (and additionally, access to a test Rails 6 app, if you have one handy, otherwise I'll spin up a new one later this week or next.)

kerrizor avatar May 14 '19 07:05 kerrizor

Just a note also that this is likely another case where I'm going to get bit by the CLI/rake task split. It remains a thorn in my side.

kerrizor avatar May 14 '19 07:05 kerrizor

@kerrizor thanks for taking the time!

sadly even with the updated gem it blows up :/ (works fine when I do the Zeitwerk::Loader.eager_load_all before)

$ rake erd --trace
** Invoke erd (first_time)
** Invoke erd:generate (first_time)
** Invoke erd:check_dependencies (first_time)
** Execute erd:check_dependencies
** Invoke erd:options (first_time)
** Execute erd:options
** Invoke erd:load_models (first_time)
** Execute erd:load_models
Loading application environment...
** Invoke environment (first_time)
** Execute environment
Loading code in search of Active Record models...
** Execute erd:generate
Generating Entity-Relationship Diagram for 0 models...
rake aborted!
No entities found; create your models first!
/Users/donschado/.rvm/gems/ruby-2.6.1/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:186:in `block in filtered_entities'
/Users/donschado/.rvm/gems/ruby-2.6.1/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:185:in `tap'
/Users/donschado/.rvm/gems/ruby-2.6.1/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:185:in `filtered_entities'
/Users/donschado/.rvm/gems/ruby-2.6.1/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:135:in `generate'
/Users/donschado/.rvm/gems/ruby-2.6.1/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:119:in `create'
/Users/donschado/.rvm/gems/ruby-2.6.1/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:74:in `create'
/Users/donschado/.rvm/gems/ruby-2.6.1/gems/rails-erd-1.6.0/lib/rails_erd/tasks.rake:61:in `block (2 levels) in <main>'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:273:in `block in execute'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:273:in `each'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:273:in `execute'
/Users/donschado/.rvm/gems/ruby-2.6.1/gems/bugsnag-6.11.1/lib/bugsnag/integrations/rake.rb:18:in `execute_with_bugsnag'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:214:in `block in invoke_with_call_chain'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:194:in `invoke_with_call_chain'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:238:in `block in invoke_prerequisites'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:236:in `each'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:236:in `invoke_prerequisites'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:213:in `block in invoke_with_call_chain'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:194:in `invoke_with_call_chain'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/task.rb:183:in `invoke'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:160:in `invoke_task'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:116:in `each'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:116:in `block in top_level'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:125:in `run_with_threads'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:110:in `top_level'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:83:in `block in run'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:186:in `standard_exception_handling'
/Users/donschado/.rvm/rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:80:in `run'
bin/rake:4:in `<main>'
Tasks: TOP => erd => erd:generate

DonSchado avatar May 14 '19 11:05 DonSchado

For versions Rails 6.0.0.rc1 and RailsERD 1.6.0.

My workaround for this was to modify config/environments/development.rb like so:

diff --git a/config/environments/development.rb b/config/environments/development.rb
index 66df51f..1c45d7c 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -6,8 +6,8 @@ Rails.application.configure do
   # since you don't have to restart the web server when you make code changes.
   config.cache_classes = false
 
-  # Do not eager load code on boot.
-  config.eager_load = false
+  # Do eager load code on boot for rails_erd (was false by default)
+  config.eager_load = true
 
   # Show full error reports.
   config.consider_all_requests_local = true

However, only the plain erd command works; rake erd still gives the following:

$ rake erd
Loading application environment...
Loading code in search of Active Record models...
Generating Entity-Relationship Diagram for 0 models...
rake aborted!
No entities found; create your models first!
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:186:in `block in filtered_entities'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:185:in `tap'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:185:in `filtered_entities'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:135:in `generate'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:119:in `create'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:74:in `create'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/tasks.rake:61:in `block (2 levels) in <main>'
/home/qianm/.gem/ruby/2.6.0/gems/rake-12.3.2/exe/rake:27:in `<top (required)>'
Tasks: TOP => erd => erd:generate
(See full trace by running task with --trace)

zqianem avatar May 22 '19 15:05 zqianem

My temporary fix:

File lib/tasks/auto_generate_diagram.rake

# frozen_string_literal: true

if Rails.env.development?
  RailsERD.load_tasks

  # TMP Fix for Rails 6.
  Rake::Task["erd:load_models"].clear

  namespace :erd do
    task :load_models do
      say "Loading application environment..."
      Rake::Task[:environment].invoke

      say "Loading code in search of Active Record models..."
      Zeitwerk::Loader.eager_load_all
    end
  end
end

maximeg avatar Aug 04 '19 10:08 maximeg

This issue has returned in 6.0.1.

@maximeg's solution fixes the issue for rake, but not the CLI (which I don't care about).

philliplongman avatar Nov 20 '19 19:11 philliplongman

One note here: I was having the issues with rake erd in rails 6.0.1 (It was seeing any of my models) but bundle exec erd still worked for me.

Andrew-Max avatar Dec 02 '19 09:12 Andrew-Max

Since Rails 6 does not play well with some gems due to the eager_load, so just add a flag to temporary enable the eager_load as below

diff --git a/config/environments/development.rb b/config/environments/development.rb
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -6,8 +6,8 @@ Rails.application.configure do 

-  # Do not eager load code on boot.
-  config.eager_load = false
+  # Do eager load code on boot by environment variable
+  config.eager_load = ENV.fetch("EAGER_LOAD", false).present?

then just add EAGER_LOAD when running erd

$ EAGER_LOAD=1 bundle exec erd

yeuem1vannam avatar Dec 23 '19 06:12 yeuem1vannam

This issue was solved? Rails-erd gem still did not generate anything on my rails 6.0.2.1. And eager_load did not work.

say8425 avatar Jan 27 '20 09:01 say8425

For versions Rails 6.0.0.rc1 and RailsERD 1.6.0.

My workaround for this was to modify config/environments/development.rb like so:

diff --git a/config/environments/development.rb b/config/environments/development.rb
index 66df51f..1c45d7c 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -6,8 +6,8 @@ Rails.application.configure do
   # since you don't have to restart the web server when you make code changes.
   config.cache_classes = false
 
-  # Do not eager load code on boot.
-  config.eager_load = false
+  # Do eager load code on boot for rails_erd (was false by default)
+  config.eager_load = true
 
   # Show full error reports.
   config.consider_all_requests_local = true

However, only the plain erd command works; rake erd still gives the following:

$ rake erd
Loading application environment...
Loading code in search of Active Record models...
Generating Entity-Relationship Diagram for 0 models...
rake aborted!
No entities found; create your models first!
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:186:in `block in filtered_entities'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:185:in `tap'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:185:in `filtered_entities'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:135:in `generate'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:119:in `create'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/diagram.rb:74:in `create'
/home/qianm/.gem/ruby/2.6.0/gems/rails-erd-1.6.0/lib/rails_erd/tasks.rake:61:in `block (2 levels) in <main>'
/home/qianm/.gem/ruby/2.6.0/gems/rake-12.3.2/exe/rake:27:in `<top (required)>'
Tasks: TOP => erd => erd:generate
(See full trace by running task with --trace)

Worked perfectly.

giedriusr avatar Feb 04 '20 09:02 giedriusr

With Rails 6.0.2.1 the above fix (enabling eager loading) isn't sufficient. Rails ERD reports finding three models (out of 10) and only draws two.

DouglasUrner avatar Feb 08 '20 23:02 DouglasUrner

you can create a initializer that fixes it. This should also help with other older gems that use eager_load!. Not sure if it can give problems

module Rails
  class Application
    def eager_load!
      Zeitwerk::Loader.eager_load_all
    end
  end
end

danielnielsennumber1 avatar Mar 18 '20 08:03 danielnielsennumber1

The non-invasive option that worked for me was

added to application.rb:

    if Rails.env.development?
      def eager_load!
        Zeitwerk::Loader.eager_load_all
      end
    end

also I had to install graphviz:

sudo apt-get install graphviz

yshmarov avatar Apr 14 '20 12:04 yshmarov

Works for me again!

This appears to be resolved by Rails 6.0.3 which makes Rails::Application#eager_load! available again:

  • Rails::Application#eager_load! is available again to load application code manually as it was possible in previous versions.

    Please, note this is not integrated with the whole eager loading logic that runs when Rails boots with eager loading enabled, you can think of this method as a vanilla recursive code loader.

    This ability has been restored because there are some use cases for it, such as indexers that need to have all application classes and modules in memory.

    Xavier Noria

(Xavier is also the author of the Zeitwerk loader.)

ansonhoyt avatar May 06 '20 18:05 ansonhoyt

Updating to Rails Rails 6.0.3 did solve it for me as well

kaka-ruto avatar Jul 03 '20 00:07 kaka-ruto

I am running Rails 6.1.3.1

I get the following error: Loading application in 'FBBDraftP'... Generating entity-relationship diagram for 41 models... Failed: NoMethodError: undefined method "parent" for FBBDraftP::Application:Class Did you mean? present?

weiserma avatar Apr 20 '21 14:04 weiserma

@weiserma this error looks related to Rails 6.1 removing Module#parent in https://github.com/rails/rails/commit/167b4153cac0069a21e0bb9689cb16f34f6abbaa. I needed to handle this for exception_notifier, so maybe that's why I didn't notice rails-erd needing it? 😄

Here's my workaround code, adding the deleted methods back to my app: https://gist.github.com/ansonhoyt/87fdb8eca4af6392481a2b55728610be

If you find this is the right fix, it'd be an easy PR if you copy the solution proposed on https://github.com/smartinez87/exception_notification/pull/504.

ansonhoyt avatar Apr 20 '21 15:04 ansonhoyt

@weiserma @ansonhoyt thanks for the report! I haven't had a chance to run down 6.1 issues (and really, we still need to look hard at the CLI.. I think a rewrite for a 2.0 release in the future might be in the works, as I'd like to deprecate some code that is propping up really old Rails versions, reduce our dependence on graphviz, etc..)

kerrizor avatar Apr 20 '21 16:04 kerrizor

I am having this issue as well - using rails 7.0.3. I only have 1 model at the moment, no controllers, no views... still getting "no entities found, create your models first!"

tkhobbes avatar Jun 13 '22 10:06 tkhobbes