rails-erd
rails-erd copied to clipboard
NoMethodError: undefined method `name' for nil:NilClass (seems to be related to PaperTrail)
There seems to have been a fix back in 2019 but it was not merged and the author has since deleted their fork.
Given it seems to be related to PaperTrail I excluded all classes descendent from PaperTrail::Version in .erdconfig but this did not help. I found the list of Version models as such:
Zeitwerk::Loader.eager_load_all
PaperTrail::Version.descendants.map(&:name).sort.join(',')
I did some digging and it seems to be related to a relationship.destination being nil:
From: /Users/kris/.gem/ruby/3.2.2/gems/rails-erd-1.7.2/lib/rails_erd/domain.rb:111 RailsERD::Domain#relationships_mapping:
104: def relationships_mapping
105: @relationships_mapping ||= {}.tap do |mapping|
106: relationships.each do |relationship|
107: (mapping[relationship.source.name] ||= []) << relationship
108: (mapping[relationship.destination.name] ||= []) << relationship
109: rescue StandardError => e
110: binding.pry
=> 111: end
112: end
113: end
[9] pry(#<RailsERD::Domain>)> e
=> #<NoMethodError: undefined method `name' for nil:NilClass>
[10] pry(#<RailsERD::Domain>)> relationship
=> #<RailsERD::Domain::Relationship:0x000000000b1da0 @source=Item @destination=>
[11] pry(#<RailsERD::Domain>)> relationship.destination
=> nil
[12] pry(#<RailsERD::Domain>)> relationship.destination.name
NoMethodError: undefined method `name' for nil:NilClass
I fixed it by opening the classes
module RailsERD
class Diagram
class Graphviz < Diagram
module Uml
each_relationship do |relationship|
from, to = relationship.source, relationship.destination
next unless to # This is the fix.
unless draw_edge from&.name, to&.name, relationship_options(relationship)
from.children.each do |child|
draw_edge child&.name, to&.name, relationship_options(relationship)
end
to.children.each do |child|
draw_edge from&.name, child&.name, relationship_options(relationship)
end
end
end
end
end
end
end
AND
module RailsERD
class Domain
def relationships_mapping
@relationships_mapping ||= {}.tap do |mapping|
relationships.each do |relationship|
(mapping[relationship.source&.name] ||= []) << relationship # This is the fix.
(mapping[relationship.destination&.name] ||= []) << relationship # This is the fix.
end
end
end
end
end
/usr/local/bundle/gems/rails-erd-1.7.2/lib/rails_erd/diagram/graphviz.rb:161:in `<module:Uml>': undefined method `each_relationship' for RailsERD::Diagram::Graphviz::Uml:Module (NoMethodError)
each_relationship do |relationship|
^^^^^^^^^^^^^^^^^
I fixed it like this:
# frozen_string_literal: true
if Rails.env.development? && defined?(RailsERD)
module RailsERD
class Diagram
class Graphviz < Diagram
each_relationship do |relationship|
from, to = relationship.source, relationship.destination
next unless to # This is the fix.
unless draw_edge from&.name, to&.name, relationship_options(relationship)
from.children.each do |child|
draw_edge child&.name, to&.name, relationship_options(relationship)
end
to.children.each do |child|
draw_edge from&.name, child&.name, relationship_options(relationship)
end
end
end
end
end
end
module RailsERD
class Domain
def relationships_mapping
@relationships_mapping ||= {}.tap do |mapping|
relationships.each do |relationship|
(mapping[relationship.source&.name] ||= []) << relationship # This is the fix.
(mapping[relationship.destination&.name] ||= []) << relationship # This is the fix.
end
end
end
end
end
end