Relationship not being passed to notification?

♀尐吖头ヾ 提交于 2020-03-06 04:38:26

问题


I created a notification that I am passing a model to:

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,
        ];
    }
}

And this is how I call the notification:

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

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

The problem is that when the notification prints the log (Log::info($this->message);), the topic relationship doesn't show up.

However, I found that if I change the toArray() function in the nofitication class to this, it prints out fine:

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

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

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

Why? How do I fix this?


回答1:


Your notification is set to queue, and the Notification class you're extending uses the SerializesModels trait. When an object with the SerializesModels trait is serialized to be put on the queue, any Models contained on that object (e.g. your message) are replaced with just the id of that model (the message id). When the queue worker unserializes your notification to process it, it will use that message id to re-retrieve the message from the database. Unfortunately, when this happens, no relationships are included.

So, even though your message had the topic relationship loaded when it was serialized, it will not have the topic relationship loaded when the queue worker processes the notification. If you need the topic inside of your notification, you will need to reload it, as you have seen.

You can read more about this in the documentation here. The relevant part is quoted below:

In this example, note that we were able to pass an Eloquent model directly into the queued job's constructor. Because of the SerializesModels trait that the job is using, Eloquent models will be gracefully serialized and unserialized when the job is processing. If your queued job accepts an Eloquent model in its constructor, only the identifier for the model will be serialized onto the queue. When the job is actually handled, the queue system will automatically re-retrieve the full model instance from the database. It's all totally transparent to your application and prevents issues that can arise from serializing full Eloquent model instances.



来源:https://stackoverflow.com/questions/44231030/relationship-not-being-passed-to-notification

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!