关系没有传递到通知?

0 laravel eloquent laravel-5 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,
        ];
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

$user->notify(new NewMessage($message));
Run Code Online (Sandbox Code Playgroud)

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

但是,我发现如果我toArray()将 nofitication 类中的函数更改为这个,它打印出来的效果很好:

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

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

    return [
        'message_id' => $this->message->id,
    ];
}
Run Code Online (Sandbox Code Playgroud)

为什么?我该如何解决?

pat*_*cus 5

注意:此问题/答案仅与 Laravel < 5.6 相关。从 Laravel 5.6 开始,加载的关系也被序列化了,所以这个问题已经不是问题了。


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

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

您可以在此处的文档中阅读有关此内容的更多信息。相关部分引述如下:

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