ruby-on-rails - Rails 服务中的 DRY 单例类
问题描述
我正在使用 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
我的问题是我最终得到了 n 个具有相同类方法的文件。当我尝试将其直接提取到抽象类时,我收到一个错误,我的调查达到了无法继承单例类的程度。
在搜索了一些答案之后,我关注了这个帖子,我试图把它擦干
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 空格字符,ruby 解释器将其识别为正在调用的方法的名称。
我把你的代码扔进了我的终端,得到了和你完全相同的错误,但是在手工编写并逐个方法执行之后,没有得到它。
在网上找到了一个转换器,在复制/粘贴您的代码(这里是我使用的那个的链接)之后,代码运行时没有出现该错误。
因此,正确格式化文件应该可以解决您遇到的特定错误。
推荐阅读
- javascript - css 选择器只选择第一个子文本而不是 div
- sql - 如何将一列中的多个值(整数)与另一列中的描述(字符)值相加?
- python - 我正在尝试使用 graphics.py 库创建一个宽度 = 100 和长度 = 50 的矩形。我对如何指定长度有点困惑
- atom-editor - 为什么 Atom 编辑器停止为长行代码着色?
- javascript - Firestore:更新不同的嵌套对象
- excel - Excel VBA:无法访问表单控件?
- html - R网页抓取困难--为什么我不能从一个多页的网站上得到所有的listing价格?
- python - 异步长时间运行的操作 API 调用
- docker - 如何在不使用 GPU 的情况下使用 nvidia-docker?
- swift - 如何在我的 for 循环之外执行代码(需要等到循环完成从 Firebase 数据库中检索数据)?