Its because when the $data is queued, laravel recognises that $data is actually a User model and so only queues the model ID. Later when the job is run, the model is fetched from the database, but subject is not a model property so it does not get restored.
One solution is to just pass them separately.
use App\Models\User;
class SendTestEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected User $user;
protected string $subject;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(User $user, string $subject)
{
$this->user = $user;
$this->subject = $subject;
logger('__construct()'.$this->subject);
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
logger('handle(): '.$this->subject);
Mail::to($user->email)->send(new AppMailer($user));
}
}
Email model:
public static function sendTestEmail()
{
SendTestEmail::dispatch(auth()->user(), 'Test email');
}
ps, in PHP 8.1, you can simplify
/**
* Create a new job instance.
*
* @return void
*/
public function __construct (
protected User $user,
protected string $subject
) {
logger('__construct()'.$this->subject);
}