Я работаю с моделью персистентности Elasticsearch, и у меня есть несколько общих методов для каждого индекса.
Учитывая индекс событий, у меня есть класс обслуживания, в котором определены некоторые методы, то же самое относится и к другим n индексам, построенным из их моделей.
class EventSearchService
class << self
def with_index(index_name)
old_repository = repository
@repository = EventSearchService::ElasticsearchEventRepository.new(index_name: index_name)
yield
ensure
@repository = old_repository
end
def index_name
repository.index_name
end
def index_all(event_documents)
return unless event_documents.present?
actions = event_documents.map do |e|
{ index: { _index: index_name, _id: e.id, _type: "_doc", data: e.to_hash }}
end
repository.client.bulk(body: actions)
end
protected
def repository
@repository ||= EventSearchService::ElasticsearchEventRepository.new
end
end
end
Моя проблема в том, что я закончил создать файлы с одинаковыми методами. Когда я пытаюсь извлечь его непосредственно в абстрактный класс, я получаю сообщение об ошибке, исследование которого доходит до такой степени, что одноэлементные классы не могут быть унаследованы.
После поиска некоторых ответов я последовал за этот поток , и я попытался DRY его
require 'forwardable'
require 'singleton'
class ElasticsearchService
include Singleton
class << self
extend Forwardable
def_delegators(
:with_index,
:index_name,
:index_all,
:repository
)
end
def with_index(index_name)
old_repository = repository
@repository = search_repository.new(index_name: index_name)
yield
ensure
@repository = old_repository
end
def index_name
repository.index_name
end
def index_all(documents)
return unless documents.present?
actions = documents.map do |d|
{ index: { _index: index_name, _id: d.id, _type: "_doc", data: e.to_hash }}
end
repository.client.bulk(body: actions)
end
def search_repository
fail "Needs to be overriden"
end
protected
def repository
@repository ||= search_repository.new
end
end
И я включил его как
class EventSearchService < ElasticsearchService
def search_repository
EventSearchService::ElasticsearchEventRepository
end
end
Я отредактировал код, чтобы он был маленьким, простым и связан с причиной, но хотел показать различные аспекты этого. Извините, если чтение слишком длинное.
Я получаю ошибку:
`<class:ElasticsearchService>': undefined local variable or method `' for ElasticsearchService:Class (NameError)