Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
refactoring index to model map concern into Registry to address #838
…and improve autoloader compatibility
  • Loading branch information
vanboom committed Nov 11, 2023
commit 11df40bd07a1e2ecbff8a2467061e97ee79ed238
16 changes: 7 additions & 9 deletions elasticsearch-model/lib/elasticsearch/model/adapters/multiple.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,14 @@ def __ids_by_type
#
def __type_for_hit(hit)

key = "#{hit[:_index]}::#{hit[:_type]}" if hit[:_type] && hit[:_type] != '_doc'
key = hit[:_index] unless key

# DVB -- not sure the ramifications of this - but do not memoize the model/klass
# I do not think that caching the types is necessary, minimal processing savings
# at the expense of broken STI autoloading in development, see #848
Registry.all.detect do |model|
(model.index_name == hit[:_index] && __no_type?(hit)) ||
(model.index_name == hit[:_index] && model.document_type == hit[:_type])
key = if hit[:_type] && hit[:_type] != '_doc'
"#{hit[:_index]}::#{hit[:_type]}"
else
hit[:_index]
end

# DVB -- #838, refactor the lookup of index name to model into the Registry
Registry.lookup(key, hit[:_type])
end

def __no_type?(hit)
Expand Down
45 changes: 44 additions & 1 deletion elasticsearch-model/lib/elasticsearch/model/multimodel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ module Elasticsearch
module Model

# Keeps a global registry of classes that include `Elasticsearch::Model`
#
# Keeps a global registry of index to class mappings
class Registry
def initialize
@models = []
@indexes = {}
end

# Returns the unique instance of the registry (Singleton)
Expand All @@ -45,22 +46,64 @@ def self.all
__instance.models
end

def self.indexes
__instance.indexes
end

def self.add_index(index, model)
__instance.add_index(index, model)
end

# Adds a model to the registry
#
def add(klass)
# Detect already loaded models and ensure that a duplicate is not stored
if i = @models.index{ |_class| _class.name == klass.name }
@models[i] = klass
# clear the cached index map (autoloading in development causes this)
@indexes.clear
else
@models << klass
end
end

def add_index(index, model)
@indexes[index] = model
end

# Returns a copy of the registered models
#
def models
@models.dup
end

def indexes
@indexes.dup
end

##
# Find the model matching the given index and document type from a search hit
# Cache the index->model mapping for performance
# Clear the index cache when models are reloaded
def self.lookup(index, type=nil)
if Registry.indexes.has_key?(index)
# Cache hit
Registry.indexes[index]
else
# Cache bust
model = if type.nil? or type == "_doc"
# lookup strictly by index for generic document types
Registry.all.detect{|m| m.index_name == index}
else
# lookup using index and type
Registry.all.detect{|m| m.index_name == index and model.document_type == type}
end
# cache the index to model mapping
Registry.add_index(index, model)
model
end
end

end

# Wraps a collection of models when querying multiple indices
Expand Down