Как l oop сервисный объект в Rails - PullRequest
0 голосов
/ 18 июня 2020

Я сделал код очень простым

Предположим, что когда я позвоню Class.new(object).call, он вернет ответ.

Цель проста

Я хочу l oop услуга, например

/ service / update_many_post.rb

class UpdateManyPost

   def call
     posts.each do |post|
       UpdateAPost.new(post: post).call
     end
   end

   private

   def posts
     Post.all
   end
end

/ service / update_a_post.rb

class UpdateAPost
       def initialize(post:)
          @post = post
       end

       def call
          @post.title = "I am great"
          @post.save
       end
  end

Хочу вызвать рейк-задание

UpdateManyPost.new.call do |response|
   # but seems like when i do, Nothing is return from the call.
   Rails.logger.info(response)

end

Ответы [ 2 ]

2 голосов
/ 18 июня 2020

Причина, по которой ваш текущий код задачи rake, похоже, ничего не возвращает, заключается в том, что ваш метод UpdateManyPost.new.call не принимает блок. Он вызывается, но ваш блок с response вообще не используется.

Чтобы код задачи rake работал так, как он у вас есть, вам нужно, чтобы UpdateManyPost#call принимал аргумент блока , и перебирать каждый post в posts, давая результат выполнения UpdateAPost#call:

# service/update_many_post.rb
class UpdateManyPost
  def call(&block)
    posts.each do |post|
      response = UpdateAPost.new(post: post).call
      yield response
    end
  end

  ...
end

Еще лучше было бы использовать posts.find_each, пакетную утилиту, которую предлагает ActiveRecord, которая автоматически разбивает запрос на страницы с помощью LIMIT и OFFSET, чтобы загружать в память только 1000 результатов за раз. По сути, он взаимозаменяем с posts.each; он будет перебирать все результаты, он просто автоматически обрабатывает пакетирование за вас.

0 голосов
/ 18 июня 2020

В своей задаче rake попробуйте это ...

response = UpdateManyPost.new.call
Rails.logger.info(response)

Вместо перебора сообщений и обновления каждого из них вы можете использовать метод update_all, предоставляемый ActiveRecord.

class UpdateManyPost

   def call
     posts.update_all(title: "I am great")
   end

   private

   def posts
     Post.all
   end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...