Вызов класса обслуживания из активного класса работы в рельсах - PullRequest
0 голосов
/ 18 марта 2020

У меня есть класс контроллера rails, который вызывает мой активный класс заданий

class Api::V2::Events::WegSessionsController < Api::V2::Events::ApplicationController
before_action :load_service

.... some code

def synchronize
@service.keep_cancelled = params[:keep_cancelled].to_b
if @service.valid_connection?

  WegJob.perform_later

  render json: {
    status: :ok,
    message: @service.message
  }, status: :ok
else
  render json: {
    status: :unprocessable_entity,
    errors: @event.errors.full_messages
  }, status: :ok
end
end

... some code

def load_service
  @service = WegService.new(event: @event)
end
end

Я настроил свой класс заданий в своем проекте Rails на использование Sidekiq и вызов метода сервиса здесь

class WegJob < ApplicationJob
queue_as :default

def perform(*args)
 WegService.synchronize
end
end

В этом классе обслуживания есть реализация метода синхронизации, который я буду вызывать из класса своей работы

class WegService
 include ActiveModel::Model

... some code

def synchronize
 if event.weg_synced_at.present?
  update
 else
  create
 end

 event.update(weg_synced_at: Time.current)
end

... some code along with update and create method implementations.
end

Когда я делаю это, я получаю следующую ошибку

[ActiveJob] [WegJob] [fd7c1869-6909-471c-bf32-9b2270a8c39c] Error performing 
WegJob (Job ID: fd7c1869-6909-471c-bf32-9b2270a8c39c) from Async(default) in 
2556.3ms: NoMethodError (undefined method `synchronize' for WegService:Class):

Я знаю, что мой способ вызова метода обслуживания из класса Job неправильный. Где я мог ошибиться?

1 Ответ

0 голосов
/ 18 марта 2020

Вы определяете метод экземпляра в WegService:

class WegService
 include ActiveModel::Model

... some code

def synchronize
 if event.weg_synced_at.present?
  update
 else
  create
 end

 event.update(weg_synced_at: Time.current)
end

... some code along with update and create method implementations.
end

И все же вы вызываете его, как если бы это был метод класса:

class WegJob < ApplicationJob
  queue_as :default

  def perform(*args)
    WegService.synchronize
  end
end

Конечно, это не так Работа. Либо переопределите метод как метод класса, либо создайте метод фабрики:

class WegService
  include ActiveModel::Model

  #.. some code

  def synchronize
    if event.weg_synced_at.present?
      update
    else
      create
    end

    event.update(weg_synced_at: Time.current)
  end

  def self.syncronize
    WegService.new.synchronize
  end
  # ... some code along with update and create method implementations.
end

Но это крайне сомнительный дизайн для объекта службы. Имя далеко не расплывчато, и сервисные объекты действительно должны иметь только метод вызова. include ActiveModel::Model также говорит мне, что то, что вы создаете, на самом деле просто модель.

...