elasticsearch-rails: Invalid single-table inheritance type: SubClass is not a subclass of Class
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-patched 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-patch 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.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 11
- Comments: 18 (7 by maintainers)
@PhilCoggins thanks for the extra info, I’ll keep investigating.
I would consider the
ActiveRecord::SubclassNotFound
a derivative of the core issue.Somehow, when a
klass
is first added to the@models
array, it initially contains nodescendants
, but subsequently performing a search the descendant is added.When code is reloaded, however, the
klass
is added to the@models
array, and a search is performed, the descendants don’t get added.Using your branch of
elasticsearch-model
on my test project:I hope this helps.