6

Sto usando DelayedJob e vorrei aggiornare la mia app Rails 4.2 per utilizzare ActiveJob. Il problema è che ho un sacco di posti di lavoro personalizzato che assomigliano a questo:Come utilizzare i lavori personalizzati delayed_job con ActiveJob?

AssetDeleteJob = Struct.new(:user_id, :params) do 
    def perform 
    # code 
    end 
    # more methods n' stuff 
end 

Poi, in un controller da qualche parte il lavoro viene accodato con la seguente sintassi:

@asset_delete_job = AssetDeleteJob.new(current_admin_user.id, params) 
Delayed::Job.enqueue @asset_delete_job 

mi piacerebbe trovare il equivalente per ActiveJob. Quanto sopra è fondamentalmente direttamente dai doc DJ. Usarlo per accodare una singola chiamata è semplice come chiamare il metodo di esecuzione del lavoro, proprio come con DJ. Ma le mie sono più complesse e richiedono la sintassi di DJ's Struct e gli argomenti passati.

Ecco quello che ho provato finora:

class AssetDeleteJob < ActiveJob::Base 
    queue_as :default 

    def initialize(user_id, params) 
    @user_id = user_id 
    @params = params 
    end 

    def perform 
    #code 
    end 

    # more methods n' stuff 

end 

job = AssetDeleteJob.new(1, {ids: [1,2,3]}) 

Purtroppo, l'oggetto istanziato non ha un metodo #perform_later come mi sarei aspettato. Esso ha #enqueue, ma ottengo un errore strano:

Could not log "enqueue.active_job" event. NoMethodError: undefined method `any?' for nil:NilClass

... seguito da una traccia dello stack in un array, che termina in

NoMethodError: undefined method `map' for nil:NilClass

Una strana coppia di errori, ma potrei non si suppone che acceda direttamente a #enqueue. Quanto sopra sembra che sia abbastanza per quanto riguarda ciò che ActiveJob sta cercando. Cosa mi manca?

risposta

5

Posso vedere due problemi. Innanzitutto, hai definito il metodo initialize nella tua classe di lavoro personalizzata, sovrascrivendo in tal modo il metodo initialize nella classe ActiveJob. Questo è ciò che sta causando l'eccezione a essere lanciata. Non sono sicuro che tu possa litigare con l'istanziazione di lavori attivi. Secondo, stai provando a chiamare il metodo di classe perform_later su un'istanza di quella classe, che ruby ​​non consentirà.

E 'semplice da risolvere, basta aggiungere gli argomenti al metodo perform nella classe personalizzata invece:

class AssetDeleteJob < ActiveJob::Base 
    #code 

    def perform(user_id, params) 
    #do a thing 
    end 

    #more code 
end 

e poi fare la fila il lavoro chiamando qualcosa come:

AssetDeleteJob.perform_later(1, {ids: [1,2,3]}) 
0
# in jobs/asset_delete_job.rb 
class AssetDeleteJob < ActiveJob::Base 
    queue_as :default 
    def perform(user_id, params) 
    AssetService.new(user_id, params).delete # for example 
    end 
end 

# somewhere in your controllers/assets_controller.rb 
    AssetDeleteJob.perform_later(1, {ids: [1,2,3]}) 
Problemi correlati