Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

pmusa's avatar
Level 2

model event “deleted” does not return all pivot attributes

I have a many-to-many relationship between User and Role models.

I want to save a history (logging) in my database every time I attach or detach a user to a role.

$role->users()->attach(...);

Since Laravel can't fire model events by default on pivot tables, I found I had to create my own custom pivot model. So here is what I did so far :

inside Role model :

    public function users(): MorphToMany
    {
        return $this
            ->morphedByMany(...)
            ->using(\App\Pivot\RolePivot::class) // <---------- NOTICE THIS
            ->withTimestamps();
    }

inside RolePivot model :

class RolePivot extends MorphPivot
{
    use RecordsModelHistory;
}

inside my RecordsModelHistory trait :

    protected static function bootRecordsModelHistory()
    {
        static::historisableModelEvents()->each(function ($event) {
            return static::$event(function (Model $model) use ($event) {
                /** @var self $model */
                if($event==='deleted'){dd($model);} // <---------- NOTICE THIS
                if (! $model->shouldRecordModelHistory($event)) {
                    return;
                }

                $model->saveModelHistory($event);
            });
        });
    }

the dd($model) is executed when I perform $role->users()->detach(...);. So far so good, since, indeed, detaching a user means deleting a row from the pivot table.

My problem is the following: the $model->attributes do not contain all the attributes I expected to see.

I only have role_id and model_id : https://i.imgur.com/17Q3gTk.png

eventhough my pivot table model_has_roles has columns model_type, model_id, role_id, created_at, updated_at : https://i.imgur.com/cx0VA8B.png

Why does it only return role_id and model_id, while I'd expect +3 more attributes?

Oddly enough, I successfully get all 5 attributes (aka pivot table's 5 columns) when attaching (event = created), but only 3 attributes when detaching (event = deleted)

0 likes
3 replies
itsfg's avatar

Hi @pmusa

Have you tried adding withPivot() to your users() relationship on the Role model ?

public function users(): MorphToMany
{
        return $this
        ->morphedByMany(...)
        ->using(\App\Pivot\RolePivot::class)
        ->withTimestamps()
        ->withPivot([
            'list_here',
            'the_pivot_table_attributes',
            'you_want_to_get_back_when',
            'calling_the_relationship'
    ]);
}
itsfg's avatar

If that doesn't work, maybe Laravel doesn't go check the content of the database to delete something. That could make sense. If that's the case, maybe you should check the "deleting" event (if that exists) where you can maybe still access the database record to store whatever you want.

HazemNoor's avatar

Although this is an old issue, but this may help any one else.

I came up with a solution, you can delete the relation using the pivot model directly, this will fire the deleted event with all data correctly

App\Pivot\RolePivot::whereRoleId(123)->whereModelId(456)->first()?->delete();
1 like

Please or to participate in this conversation.