2017-09-11 3 views
1

Ich habe ein Problem bei der Verwendung von Laravel Job Deserialisierung. Dies ist die Job-Klasse, die in der Datenbank der Warteschlange gestellt wird:Laravel Job Deserialzation falsche Klasse

class SendRatingEmail implements ShouldQueue 
{ 
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; 

    protected $order, $user; 

    public function __construct(User $user, Order $order) 
    { 
     $this->order = $order; 
     $this->user = $user; 
    } 

    public function handle() 
    { 
     if ($this->order->isRatedByUser($this->user->id)) { 
      return; 
     } 
     Mail::to($this->user->email)->queue(new RatingEmail($this->order, $this->user)); 
    } 
} 

In der Klasse Order.php, versende ich diesen Job so:

class Order { 
    function queueRating() 
    { 
     $when = Carbon::now()->addDays(env('ORDER_DAYS_RATING', 8)); 
     dispatch((new SendRatingEmail($this->buyer, $this))->delay($when)); 
    } 
} 

So ist das Problem in dem handle() Funktion Job, speziell der Fehler ist:

Call to undefined method Illuminate\Database\Query\Builder::isRatedByUser() 

Es scheint, als ob Laravel mir das falsche Objekt gibt, statt App\Order gibt es mir den QueryBuilder. In der queueRating() Funktion habe ich überprüft, dass die Typen im Konstruktor die erwarteten Typen sind. Ich habe getestet sogar eine Abhilfe, die nicht auch zu funktionieren scheint: Ich habe auf dem Arbeitstisch sah,

if($this->order instanceof \Illuminate\Database\Query\Builder) { 
    $this->order = $this->order->first(); 
} 

auch, und es scheint, als ob die gespeicherten Modelle korrekt sind (App\Order)

bearbeiten

Hier ist der Code, wo die queueRating() Funktion aufgerufen wird. Die Datei ist StripeController, die Kreditkartenzahlungen behandelt.

public function orderPaid($order) { 
    $order->payment_done = 1; 
    $order->save(); 

    $order->chat->open = 1; 
    $order->chat->save(); 

    $order->queueRating(); 
} 
+0

Können Sie den Code zeigen, wo Sie 'queueRating' aufrufen? Versuchen Sie auch innerhalb Ihrer Methode 'queueRating' (vor' $ when') die Methode 'isRatedByUser' aufzurufen und zu überprüfen, ob sie funktioniert. –

+0

@RossWilson Ich habe meine Frage bearbeitet, um den Code einzuschließen. –

+0

Hat das Aufrufen der 'isRatedByUser' Methode innerhalb der' queueRating' Methode funktioniert? Überprüfen Sie auch innerhalb der 'handle' Methode Ihres Jobs, ob die' Order' existiert, d. H. ('$ This-> order-> exists'). –

Antwort

0

Ich fand das Problem, wie immer das Problem ist nicht, wo ich sah. Wie sich herausstellt, ist der Code völlig in Ordnung, aber ich habe vergessen, den Warteschlangen-Worker auf dem Staging-Server neu zu starten, was bedeutet, dass Änderungen in der Codebasis nicht im Warteschlangen-Worker angewendet wurden. Die Anwendung und die Warteschlange verwendeten daher unterschiedliche Versionen.

Es wird auch in den Laravel Queue Documentation erklärt:

Denken Sie daran, Warteschlange Arbeiter langlebige Prozesse und speichern Sie den Anwendungszustand im Speicher gebootet. Daher werden Änderungen in Ihrer Codebasis nicht bemerkt, nachdem sie gestartet wurden. Achten Sie daher während des Bereitstellungsprozesses darauf, die Warteschlangen-Worker neu zu starten.

Ich verwende den Bugtracker Bugsnag, der den Fehler und auch die Zeilennummern im Code zeigt. Ich hatte bemerkt, dass die Zeilennummer, bei der der Fehler auftrat, nicht mit der tatsächlichen Zeilennummer übereinstimmte, konnte aber nicht herausfinden, dass dies das Problem verursachte.