Describe the bug
Nested relations does not handle null related model correctly and instead pulls the relation via the function, choking since it's now not a model.
To Reproduce
This is a bit contrived example, but it does cut it to the most short reproduction case. Our production one makes more logical sense as to why we do this. An Item has a Material, which has a Cut, which has a property called name, thus requesting the attribute "material.cut.name" on the Item model. This one always exists, but we have a backMaterial relation, which does not.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
class Test extends Model
{
use LogsActivity;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly([
// disabled to show the edge case in isolation
// "*",
// "parent.name",
"parent.parent.name",
]);
}
public function parent()
{
return $this->belongsTo(self::class, "parent_id");
}
}
Test::create(); //exception, record still created though
Test::whereNull("parent_id")->first()->delete(); //exception, the record is deleted
Test::whereHas("parent", fn($q) => $q->whereNull("parent_id")->first()->delete(); //exception, the record is deleted
Expected behavior
No exceptions.
Screenshots
N/A
Versions (please complete the following information)
PHP: 8.2.11
Database: Microsoft SQL Server 2019 - 15.0.2104.1 (X64) , pdo_sqlsrv/sqlsrv 5.11.1
Laravel: v10.28.0
Package: 4.7.3
Additional context
A possible fix for this might be this, though someone can also argue that some part of this is a breaking change.
It's also possible it's decided that it's not a supported case and should explicitly throw an error for it instead of getRelatedModelRelationName throwing a TypeError when given a non model. Looks like the original logic was added in 09035a48ad01943cc1eb553b3baf4058b6d7cab0 (v1.12.0), blame stopped add 5a345aca0abca4fe8cd0263f19b86d1760fac02b (v4.0.0), but I found the thread.
As an aside, this also does not handle HasMany like relations which have a collection, but also they have no special handling anyways up until this point.
ExceptionApp\Models\TestModel::getRelatedModelRelationName(): Argument #1 ($model) must be of type Illuminate\Database\Eloquent\Model, Illuminate\Database\Eloquent\Relations\BelongsTo given, called in /var/www/html/vendor/spatie/laravel-activitylog/src/Traits/LogsActivity.php on line 398 {"userId":67,"exception":"[object] (TypeError(code: 0): App\\Models\\Inventory\\MaterialManagement\\MaterialItem::getRelatedModelRelationName(): Argument #1 ($model) must be of type Illuminate\\Database\\Eloquent\\Model, Illuminate\\Database\\Eloquent\\Relations\\BelongsTo given, called in /var/www/html/vendor/spatie/laravel-activitylog/src/Traits/LogsActivity.php on line 398 at /var/www/html/vendor/spatie/laravel-activitylog/src/Traits/LogsActivity.php:408)
because this issue seems to be inactive for quite some time now, I've automatically closed it. If you feel this issue deserves some attention from my human colleagues feel free to reopen it.
Describe the bug Nested relations does not handle null related model correctly and instead pulls the relation via the function, choking since it's now not a model.
To Reproduce This is a bit contrived example, but it does cut it to the most short reproduction case. Our production one makes more logical sense as to why we do this. An
Item
has aMaterial
, which has aCut
, which has a property calledname
, thus requesting the attribute"material.cut.name"
on theItem
model. This one always exists, but we have abackMaterial
relation, which does not.Expected behavior No exceptions.
Screenshots N/A
Versions (please complete the following information)
Additional context A possible fix for this might be this, though someone can also argue that some part of this is a breaking change.
It's also possible it's decided that it's not a supported case and should explicitly throw an error for it instead of
getRelatedModelRelationName
throwing a TypeError when given a non model. Looks like the original logic was added in 09035a48ad01943cc1eb553b3baf4058b6d7cab0 (v1.12.0), blame stopped add 5a345aca0abca4fe8cd0263f19b86d1760fac02b (v4.0.0), but I found the thread.As an aside, this also does not handle
HasMany
like relations which have a collection, but also they have no special handling anyways up until this point.Exception
App\Models\TestModel::getRelatedModelRelationName(): Argument #1 ($model) must be of type Illuminate\Database\Eloquent\Model, Illuminate\Database\Eloquent\Relations\BelongsTo given, called in /var/www/html/vendor/spatie/laravel-activitylog/src/Traits/LogsActivity.php on line 398 {"userId":67,"exception":"[object] (TypeError(code: 0): App\\Models\\Inventory\\MaterialManagement\\MaterialItem::getRelatedModelRelationName(): Argument #1 ($model) must be of type Illuminate\\Database\\Eloquent\\Model, Illuminate\\Database\\Eloquent\\Relations\\BelongsTo given, called in /var/www/html/vendor/spatie/laravel-activitylog/src/Traits/LogsActivity.php on line 398 at /var/www/html/vendor/spatie/laravel-activitylog/src/Traits/LogsActivity.php:408)
Stack Trace