关系没有传递给通知?

时间:2017-05-28 19:08:37

标签: laravel laravel-5 eloquent laravel-5.3 laravel-eloquent

我创建了一个通知我将模型传递给:

class NewMessage extends Notification implements ShouldQueue
{
    use Queueable;

    protected $message;

    public function __construct(Message $message)
    {
        $this->message = $message;
    }

    public function via()
    {
        return ['database'];
    }

    public function toArray()
    {
        Log::info($this->message);

        return [
            'message_id' => $this->message->id,
        ];
    }
}

这就是我调用通知的方式:

$message = Message::where('user_id', Auth::user()->id)
    ->where('message_id', $message_id)
    ->with('topic')
    ->get();

$user->notify(new NewMessage($message));

问题是,当通知打印日志(Log::info($this->message);)时,topic关系不会显示。

然而,我发现如果我将nofitication类中的toArray()函数更改为此函数,它会打印出来:

public function toArray()
{
    $this->message->topic;

    Log::info($this->message);

    return [
        'message_id' => $this->message->id,
    ];
}

为什么呢?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

您的通知设置为队列,并且您要扩展的Notification类使用SerializesModels特征。当具有SerializesModels特征的对象被序列化以放入队列时,该对象上包含的任何模型(例如您的消息)将仅替换为该模型的ID(消息ID)。当队列工作程序对您的通知进行反序列化以对其进行处理时,它将使用该消息ID从数据库中重新检索该消息。不幸的是,当发生这种情况时,不会包含任何关系。

因此,即使您的消息在序列化时加载了主题关系,但在队列工作程序处理通知时也不会加载主题关系。如果您需要通知中的主题,则需要重新加载,如您所见。

您可以在documentation here中详细了解相关信息。相关部分引用如下:

  

在此示例中,请注意我们能够将Eloquent模型直接传递到排队作业的构造函数中。由于作业正在使用SerializesModels特征,因此在处理作业时,Eloquent模型将被优雅地序列化和反序列化。如果排队作业在其构造函数中接受Eloquent模型,则只有模型的标识符将序列化到队列中。实际处理作业时,队列系统将自动从数据库中重新检索完整的模型实例。它对您的应用程序完全透明,可以防止序列化完整的Eloquent模型实例时出现的问题。