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

NoMethodError: undefined method `name' for nil:NilClass (seems to be related to PaperTrail)

Open krisleech opened this issue 2 years ago • 2 comments

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

krisleech avatar Sep 08 '23 13:09 krisleech

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

victorhazbun avatar Oct 11 '24 05:10 victorhazbun

/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

vill avatar Aug 18 '25 05:08 vill