ruby-on-railsadministrate

Strange "rails superclass mismatch for class" on AWS, while local docker runs fine


I decided to switch the admin section of my site to administrate gem. After making all necessary changes and running all tests, everything seems fine to push to AWS. When trying to access my site, I got a 503 error. Logging into AWS showed that my Fargate tasks were crashing with the following error:

rails superclass mismatch for class EventsController

It seems that the way I defined this call seems to be wrong, but I don't understand why.

The file lives in /app/controllers/admin/ahoy/events_controller.rb and looks like this:

module Admin
  class Ahoy::EventsController < Admin::ApplicationController
  end
end

I don't need any additional logic, so it's quite basic. I thought that it could be caused by the module, so I also tried removing the Admin from the super class:

module Admin
  class Ahoy::EventsController < ApplicationController
  end
end

Strange thing is that both options seem to work fine in my local docker instance, but fail on AWS. I'm kind of struggling on how to solve this. Am I namespacing this wrong?


Solution

  • Try this:

    module Admin
      module Ahoy
        class EventsController < Admin::ApplicationController
        end
      end
    end
    

    If this solves your issue, here's why: your code has a problem, but your local environment is loading your files in an order that avoids it.

    Here's an example. Create a standalone Ruby file with these contents:

    module Admin
    end
    
    #module Admin
      #module Ahoy
      #end
    #end
    
    module Admin
      class ApplicationController
      end
    end
    
    module Ahoy
      class EventsController
      end
    end
    
    module Admin
      class Ahoy::EventsController < Admin::ApplicationController
        def self.foo
        end
      end
    end
    

    If you run this, you should see the same problem. Now uncomment the definition for Admin::Ahoy and run it again. It should not raise any error.

    With the definition for Admin::Ahoy commented, Ruby reaches the definition for Admin::Ahoy::EventsController without a pre-existing Admin::Ahoy. However it does have a module Ahoy (not namespaced, which can also be expressed as ::Ahoy), so it assumes that's the module you are referring to. Therefore, the class it tries to create is Ahoy::EventsController (nevermind you should be in the Admin namespace). The problem now is that Ahoy::EventsController already exists, and inherits from Object (the default if you don't say otherwise), while here you are saying it inherits from Admin::ApplicationController. It's a superclass mismatch, and that's what the error is talking about.

    Your application probably has a definition for Admin::Ahoy or similar. However this is not loading first in production, and that's why you are getting the error in one environment and not the other. Defining your classes with each module separately listed should avoid you similar issues in the future.