Создание хэша с вычисленными свойствами из класса обслуживания - PullRequest
3 голосов
/ 29 октября 2019

Я хотел бы помочь закончить кусок кода. Я не совсем понимаю, как объяснить, что мне нужно, поэтому я покажу вам постепенно.

У меня есть эта модель:

class Metric < ApplicationRecord
  belongs_to: :post
  after_save: :analysis!

  # The table Metrics has the following columns:
  # adverb_count
  # adverb_density
  # sentiment
  # word_count
  # letter_count

  def analysis!
    res = MetricService.call post.body
    update! res
  end
end

После сохранения экземпляра метрики мне нужновызвать внешнюю службу, которая вернет хеш, содержащий свойства, которые помогут мне вычислить значения adverb_count, adverb_density, sentiment, word_count и, наконец, letter_count. Для этого я создал класс MetricService, который инкапсулирует эту логику:

class ApplicationService
  def self.call(*args, &block)
    new(*args, &block).call
  end
end

class MetricService < ApplicationService
  extend Memoist

  def initiaze(text)
    @text = text
  end

  # TODO: return the
  def call
    pre_analysis
    # =>
    #  Hash containing several props

    post_nalysis
    # =>
    #  Hash containing sereral props
  end

  private

  def pre_analysis
    client.pre_analysis @text
  end
  memoize :pre_analysis

  def post_analysis
    client.post_analysis pre_analysis['id']
  end

  def client
    SDK::Service.new ENV['API_KEY']
  end
  memoize :client
end

После создания экземпляра этого класса я вызываю два метода client: pre_analysis и post_analyisи с этими двумя данными я наконец могу вычислить значения свойств adverb_count, adverb_density, sentiment, word_count, and letter_count и вернуть их в Metric. Я хотел бы создать для каждого свойства метод:

class MetricService < ApplicationService

   # ...
   def adverb_count
     # use pre_analysis and post_analysis to computate this value here
   end

   def adverb_density
     # use pre_analysis and post_analysis to computate this value here
   end

   def sentiment
     # use pre_analysis and post_analysis to computate this value here
   end

   def word_count
     # use pre_analysis and post_analysis to computate this value here
   end

   def letter_count
     # use pre_analysis and post_analysis to computate this value here
   end
   # ...
end

И из метода call я просто вызываю их и возвращаю хеш.

Из того, что я исследовал,службы в ROR должны содержать только один публичный метод, поэтому я думаю, что я должен держать эти свойства закрытымиЭто правильное предположение?

Есть ли способ построить хэш из #call, не вызывая каждый из этих методов по отдельности? Например:

def call
  {
    adverb_count: adverb_count
    # etc
  }
end

Спасибо.

1 Ответ

2 голосов
/ 29 октября 2019

Вы можете использовать метапрограммирование как:

# the only public method
def call
  %w[adverb_count adverb_density sentiment word_count letter_count].each_with_object({}) do |method_name, result|
    result[method_name] = send(method_name)
  end
end

private

def adverb_count
  # use pre_analysis and post_analysis to computate this value here
end

def adverb_density
  # use pre_analysis and post_analysis to computate this value here
end

# and so on...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...