What's zeitwerk trying to tell us with ".. is ignored because XXX is already defined"

I am looking at a nasty issue with PaperTrail. We are redefining a class in app/models/paper_trail/version.rb that looks like

puts "I am loading"
module PaperTrail
  class Version < ActiveRecord::Base
    include PaperTrail::VersionConcern

with the specs and with rails zeitwerk:check we get the message

Zeitwerk@rails.main: file /Users/kireto/…/app/models/paper_trail/version.rb is ignored because PaperTrail::Version is already defined

The text “I am loading” is never printed.

Why is app/models/paper_trail/version.rb not loaded? It is in app/models, it is in the autoloaded and eager_load paths. Does zeitwerk look only at the first definition and ignores everything after that. Because there is a PaperTrail::Version in another gem that gets loaded first then app/models/paper_trail/version.rb is never read. Right? Then what will be the correct way to redefine a constant to load from our file?

Thanks.

Hi @kmitov,

Did you get the solution for this issue? I am also running into same problem and would like to know how to solve it.

Thanks, Anand

Where is PaperTrail::Version defined?

bin/rails runner 'pp PaperTrail.const_source_location(:Version)'

I see, that is defined by paper_trail in this file.

You cannot redefine an already existing class just by creating a file with the same name (you could not either using classic), the file is ignored. This is so because the loader says: Hey, this constant already exists, so I should not be managing it (for example, I should not be unloading 3rd party code), I’ll log it and pass. The file becomes a shadowed file.

I don’t know what you want to do exactly, but if you want something custom and reloadable, you could subclass, as the code comment in that file suggests (docs).

If you really want to reopen the orginal PaperTrail::Version you can do that during initialization.