【问题标题】:DRY singleton classes in rails serviceRails 服务中的 DRY 单例类
【发布时间】:2020-04-24 12:25:09
【问题描述】:

我正在使用 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 个具有相同类方法的文件。当我尝试将其直接提取到抽象类时,我收到一个错误,我的调查达到了无法继承单例类的程度。

在搜索了一些答案后,我关注了this 线程并尝试将其干燥

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)

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 design-patterns dry


    【解决方案1】:

    这个很狡猾。 代码中有一些非 ASCII 空格字符,ruby 解释器将其识别为正在调用的方法的名称。

    我把你的代码扔进了我的终端,得到了和你一模一样的错误,但是在手工编写并逐个方法执行之后,没有得到它。

    在网上找到了一个转换器,在复制/粘贴您的代码(这里是 link to the one I used)后,代码运行时没有出现该错误。

    因此,正确格式化文件应该可以解决您遇到的特定错误。

    【讨论】:

    • 你是个天使。我不知道 vscode 是怎么识别不出来的,看看设置。一切都是正确的,但仍然是一个神秘的错误消息。
    猜你喜欢
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-28
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多