voormedia / rails-erd

Generate Entity-Relationship Diagrams for Rails applications
http://voormedia.github.io/rails-erd/
MIT License
3.96k stars 364 forks source link

Rails 6 support ? #322

Open 3pns opened 5 years ago

3pns commented 5 years ago

On the same Mac OS laptop:

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.
DonSchado commented 5 years ago

@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.

3pns commented 5 years ago

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
DonSchado commented 5 years ago

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')
kerrizor commented 5 years ago

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 commented 5 years ago

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.

DonSchado commented 5 years ago

@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
zqianem commented 5 years ago

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)
maximeg commented 4 years ago

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
philliplongman commented 4 years ago

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).

Andrew-Max commented 4 years ago

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.

yeuem1vannam commented 4 years ago

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
say8425 commented 4 years ago

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.

giedriusr commented 4 years ago

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.

DouglasUrner commented 4 years ago

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.

danielnielsennumber1 commented 4 years ago

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
yshmarov commented 4 years ago

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

ansonhoyt commented 4 years ago

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.)

kaka-ruto commented 4 years ago

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

weiserma commented 3 years ago

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?

ansonhoyt commented 3 years ago

@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.

kerrizor commented 3 years ago

@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..)

tkhobbes commented 2 years ago

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!"

rsmithlal commented 2 weeks ago

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!"

Thanks for your report. I'm looking into revisiting this gem developing my Rails 7.1 engine. I will post with my observations once I try to implement it. I've used it in past apps and it was really handy.