我创建了一个通知我将模型传递给:
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,
];
}
为什么呢?我该如何解决这个问题?
答案 0 :(得分:3)
您的通知设置为队列,并且您要扩展的Notification
类使用SerializesModels
特征。当具有SerializesModels
特征的对象被序列化以放入队列时,该对象上包含的任何模型(例如您的消息)将仅替换为该模型的ID(消息ID)。当队列工作程序对您的通知进行反序列化以对其进行处理时,它将使用该消息ID从数据库中重新检索该消息。不幸的是,当发生这种情况时,不会包含任何关系。
因此,即使您的消息在序列化时加载了主题关系,但在队列工作程序处理通知时也不会加载主题关系。如果您需要通知中的主题,则需要重新加载,如您所见。
您可以在documentation here中详细了解相关信息。相关部分引用如下:
在此示例中,请注意我们能够将Eloquent模型直接传递到排队作业的构造函数中。由于作业正在使用
SerializesModels
特征,因此在处理作业时,Eloquent模型将被优雅地序列化和反序列化。如果排队作业在其构造函数中接受Eloquent模型,则只有模型的标识符将序列化到队列中。实际处理作业时,队列系统将自动从数据库中重新检索完整的模型实例。它对您的应用程序完全透明,可以防止序列化完整的Eloquent模型实例时出现的问题。