Search code examples
laravellaravel-horizon

RelationNotFoundException error only in laravel dispatched jobs


I have a very strange error in laravel 7 where I have defined a hasOne relationship in the User Model called user_badge

public function userBadge()
{
    return $this->hasOne(UserBadge::class, 'id', 'user_badge_id');
}

I have added user_badge_id to the users table and I have also made the user_badges table which holds the badge information. When a job runs in the background, I get the following error

Illuminate\Database\Eloquent\RelationNotFoundException: Call to undefined relationship [userBadge] on model [App\User]. in /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/RelationNotFoundException.php:34

Navigating throughout the site I get no issue at all.

This issue occurs when sending an email to the job queue. It happens to all notifications that is sent. Further to this, sometimes the email does get sent but most of the time it doesn't. The code is below for one of the notification

class NewFollowUserNotification extends Notification implements ShouldQueue
{
    use Queueable;
    public $sender;
    public $receiver;

    /**
     * Create a new notification instance.
     *
     * @param User $sender
     * @param User $receiver
     */
    public function __construct(User $sender, User $receiver)
    {
        $this->sender = $sender;
        $this->receiver = $receiver;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param mixed $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        if (Profile::sendEmailNotification('NewFollowUserNotification', $this->receiver)) {
            return ['database', 'mail', 'broadcast'];
        } else {
            return ['database', 'broadcast'];
        }
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param mixed $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        $user_notifications = UserNotifications::create('NewFollowUserNotification');
        $user_notifications->setUsername($this->receiver->username);
        $user_notifications->setEmailTemplate(EmailTemplate::getDefaultEmail());
        $user_notifications->setButtonUrl(config('app.url').'/member/profiles/'.$this->sender->username);
        $notification = $user_notifications->getEmailNotification();
        $user_notifications->setTags('{receiver_first_name}', $this->receiver->first_name);
        $user_notifications->setTags('{receiver_last_name}', $this->receiver->last_name);
        $user_notifications->setTags('{receiver_full_name}', $this->receiver->first_name . ' ' . $this->receiver->last_name);
        $user_notifications->setTags('{sender_first_name}', $this->sender->first_name);
        $user_notifications->setTags('{sender_last_name}', $this->sender->last_name);
        $user_notifications->setTags('{sender_full_name}', $this->sender->first_name . ' ' . $this->sender->last_name);

        return $user_notifications->sendUserNotification($notification);
    }

    /**
     * Get the array representation of the notification.
     *
     * @param mixed $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            'heading' => 'New contact request',
            'message' => $this->sender->first_name.' '.$this->sender->last_name.
                ' sent you a contact request',
            'link' => '/member/profiles/'.$this->sender->username,
            'username' => $this->sender->username,
            'module' => 'user',
        ];
    }

Locally on my own development machine everything works fine.


Solution

  • The issue here was the serialization of models within a job. There are limitations as to how much data jobs can serialize so I ended up passing the id of the model to the job and accessing the necessary information from there.