Closed
@PhilCoggins

Description

I encountered some serious headaches while working with Elasticsearch-Model in development.

My problem is that the Invalid single-table inheritance type: X is not a subclass of Y exception was being thrown when I tried to instantiate records with the Multiple adapter after my code had been reloaded for the first time. I would have to restart my Rails server every time I made any changes to my code.

What I found was that Elasticsearch::Model::Registry.models would endlessly accumulate reloaded classes each time my code was being reloaded. If I had five classes that included Elasticsearch::Model, it would increase by 5 each time my code reloaded. I have monkey-ed the Registry class with:

  module Elasticsearch
    module Model
      class Registry
        def add(klass)
+         existing_model = @models.detect { |model| model.name == klass.name }
+         @models.delete(existing_model)
          @models << klass
        end
      end
    end
  end

in an initializer and only for development environment to fix this particular issue to ensure this Registry only contains the newly-reloaded classes.

After this change, I continued to encounter the same error. What I found was that Elasticsearch::Model::Adapter::Multiple::Records was caching the result of __type_for_hit in a class variable @@__types, and after my code was reloaded, the stale classes were being returned instead of the newly reloaded classes. I unset this class variable by hooking into Active Support's reloader:

Rails.application.reloader.before_class_unload do
  Elasticsearch::Model::Adapter::Multiple::Records.remove_class_variable(:@@__types) }
end

This is in the same environment block that the above monkey- is in to avoid affecting production environment. This allowed my records to be instantiated even after my code had been reloaded and fixed my issue.

This issue took a ton of time and effort (and frustration) to debug and fix, it would be nice to see the team provide better support for STI since this is a core feature in Rails. Hopefully this report will help you guys improve on some of these weak spots. I'm happy to provide any other information you might need.