rails 服务中的 DRY 单例 类
DRY singleton classes in rails service
我正在使用 Elasticsearch 持久化模型,并且对每个索引都有一些通用方法。
给定一个事件索引,我有一个服务class,其中定义了一些方法,其他 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
我的问题是我最终得到了 n 个使用相同 class 方法的文件。当我尝试将其直接提取为抽象 class 时,我收到一个错误,其调查使我无法继承单例 classes。
在搜索了一些答案后,我关注了 线程,并尝试将其干燥
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)
这个很狡猾。 您的代码中有一些非 ASCII space 字符,ruby 解释器将其识别为正在调用的方法的名称。
我把你的代码扔到我的终端里,得到了和你一模一样的错误,但是手写了一个方法一个方法执行后,没有得到。
在线找到一个转换器,在 copy/pasting 你的代码(这里是 link to the one I used)之后,代码 运行 没有那个错误。
因此正确格式化文件应该可以解决您遇到的特定错误。
我正在使用 Elasticsearch 持久化模型,并且对每个索引都有一些通用方法。
给定一个事件索引,我有一个服务class,其中定义了一些方法,其他 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
我的问题是我最终得到了 n 个使用相同 class 方法的文件。当我尝试将其直接提取为抽象 class 时,我收到一个错误,其调查使我无法继承单例 classes。
在搜索了一些答案后,我关注了
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)
这个很狡猾。 您的代码中有一些非 ASCII space 字符,ruby 解释器将其识别为正在调用的方法的名称。
我把你的代码扔到我的终端里,得到了和你一模一样的错误,但是手写了一个方法一个方法执行后,没有得到。
在线找到一个转换器,在 copy/pasting 你的代码(这里是 link to the one I used)之后,代码 运行 没有那个错误。
因此正确格式化文件应该可以解决您遇到的特定错误。