Rails: доступ к атрибуту из фонового работника (Stripe charge_id) - PullRequest
0 голосов
/ 27 мая 2018

Мне удалось заставить Stripe работать и обрабатывать задания, где пользователь должен заплатить единовременную плату для создания записи задания.

После перевода вызова на Stripe::Charge.create в фоновом режиме я не могу понять, как передать charge.id из Stripe::Charge.create в объект Order.

Я планировал переместить вызов Order.create в работника sidekiq и получить доступ к charge.id напрямую, но я не могу получить доступ к @job внутри работника, потому что stripeToken нельзя использовать более одного раза,Любая идея о том, как я могу сохранить charge.id в Order? (отдельно от основной модели задания)

JobsController

def create
    ...

    if @job.create_with_stripe(params[:stripeToken])
      if @job.save
        Order.create(
          # Can't figure out how to pass the charge.id from StripePaymentJob
          :charge_id    => @charge.id,
          :job_id       => @job.id
        )
      end
      ...
  end

Модель задания

def create_with_stripe(token)
    Stripe.api_key = Rails.application.secrets.stripe_secret_key

    if valid?
      StripePaymentJob.perform_later(token, SecureRandom.uuid)
    else
    ...
  end

работник полосы

class StripePaymentJob < ApplicationJob
  queue_as :default

  def perform(token, idempotent_key)
    @charge = Stripe::Charge.create({
      ...
    }, { idempotency_key: idempotent_key })
  end
end

1 Ответ

0 голосов
/ 31 мая 2018

Я бы рассмотрел этот подход:

  • Прежде чем запрашивать выполнение задания, создайте запись заказа с nil charge_id
  • После завершения транзакции Stripeзавершив работу, обновите заказ с помощью возвращенного charge_id

. Для этого вы можете положиться на globalid , который позволяет вашей работе получить доступзаказ напрямую.См. http://guides.rubyonrails.org/active_job_basics.html#globalid для получения информации.

Обновите реализацию своего задания, чтобы теперь обновлять объект после успешного завершения задания:

class StripePaymentJob < ApplicationJob  
  queue_as :default

  def perform(token, idempotent_key, order)
    @charge = Stripe::Charge.create({
      ...
    }, { idempotency_key: idempotent_key })
    order.update(charge_id: @charge.id, job_id: self.jid)
  end
end

Очевидно, что вам потребуется больше ведения журнала и обработки ошибок., поскольку это происходит в фоновом режиме, и вы не будете знать, когда и что не получится.

Ваша рабочая модель теперь будет называть execute_later как

order = Order.create
StripePaymentJob.perform_later(order, token, SecureRandom.uuid)

Дайте мне знать, если это работает,или если мне нужно обновить этот ответ.

...