Larastan: BelongsTo relation produces Model|null type

Created on 11 Jun 2021  路  11Comments  路  Source: nunomaduro/larastan

Description

I have a non-nullable database column, but it reports as being nullable by phpstan.

Parameter #1 $task of method App\Models\ExecutionStudent::getExaminerRole() expects App\Models\Task,
App\Models\Task|null given.

Laravel code where the issue was found

// models are pseudo-code, hopefully it is understandable
class Task {
  int $id
}

class Process {
  int $task_id;

  public function task(): BelongsTo
  {
    return $this->belongsTo(Task::class, 'task_id');
  }
}

$process->task // gives phpstan error

All 11 comments

Thank you for your report.

So you thing there cannot be a process that has no task?

Exactly, the migration for the processes table is as follows:

Schema::create('processes', function (Blueprint $table): void {
    $table->id();
    $table->timestamps();
    $table->string('name', 100);
    $table->string('description', 255);
    $table->foreignIdFor(Task::class, 'task_id')->constrained();
});

A process always has a task.

For now I just added '#App\\Models\\Task\|null given#' to the ignoreErrors in phpstan.neon, but ideally this wouldn't be necessary.

If you are looking for a _proper_ :) work-around.

/** @var \App\Models\Task $task */
$task = $process->task;

I hope @canvural will chime in.

If you are looking for a _proper_ :) work-around.

/** @var \App\Models\Task $task */
$task = $process->task;

Oh right, yea that's an even better work-around (something only a programmer would say ;p).

Hi,

I thought about this a little bit. At first it made sense. But then I thought what if the Task is soft deleted, or there is some other scope preventing it to be returned. In that case the relation can still return null.

So I don't think we can change this in Larastan. But it's easy to overwrite in your code. You can do:

/**
 * @property-read Task $task
 */
class Process
{
    //...
}

and this would do the trick.

Thank you.

The thing is, Task is not soft-deletable, I think it would be better to check for the existence of that trait and then make it return non-null.

For now I will add the suggestion you added. Thank you.

The thing is, Task is not soft-deletable, I think it would be better to check for the existence of that trait and then make it return non-null.

Soft delete was just an example. It can be any other constraint. So this is out of scope of a static analysis tool.

Alright, thanks for the quick response man!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danielcosta picture danielcosta  路  4Comments

AJenbo picture AJenbo  路  4Comments

grcasanova picture grcasanova  路  4Comments

mariomka picture mariomka  路  4Comments

JeroenVanOort picture JeroenVanOort  路  3Comments