jcmargentina's avatar

Prevent model update

Hello there, I am writting a TRAIT to prevent model updates if it has certain condition, in this case if its relationship to TokenDocument > 1. Is not working.

Trait

<?php

namespace App\Traits;

use Illuminate\Database\Eloquent\Model;

trait FreezeIfAttachedToToken
{
    public static function bootFreezeIfAttachedToToken()
    {
        static::saving(function (Model $model) {
            if ($model->isAttachedToToken()) {
                throw new \Exception("Cannot save: The record is attached to token");
            }
        });

        static::updating(function (Model $model) {
            if ($model->isAttachedToToken()) {
                throw new \Exception("Cannot save: The record is attached to token");
            }
        });

        static::creating(function (Model $model) {
            if ($model->isAttachedToToken()) {
                throw new \Exception("Cannot save: The record is attached to token");
            }
        });

        static::deleting(function (Model $model) {
            if ($model->isAttachedToToken()) {
                throw new \Exception("Cannot delete: The record is attached to token");
            }
        });
    }

    public function isAttachedToToken()
    {
        return (bool) $this->TokenDocument->count();
    }
}

Is not working at all, I also tried to "return false" instead of throwing an exception but ... nothing.

ANy help?I already spent 2 hours on this.

When I do something like:

$model = Model::find(id)

$model->data = "something";

$model->save()

I expect the exception, but instead model gets updated, and yes, It does meet the condition to be blocked

0 likes
3 replies
phuchautea's avatar

Hello, Assuming TokenDocument is a relationship on your model, the way you're checking if it's attached might not be correct.

You can try the code below.

public function isAttachedToToken()
{
	return $this->TokenDocument()->count() > 1;
}

public function TokenDocument()
{
	return $this->hasMany('App\TokenDocument'); // adjust this based on your actual relationship
}
Snapey's avatar

first check if it even reaches your model observer

martinbean's avatar

@jcmargentina Your updating and creating callbacks are redundant, since saving covers both of those cases. There’s also an exists method for checking if a model has any related records:

public function isAttachedToToken(): bool
{
    return $this->TokenDocument->exists();
}

It sounds like your trait isn’t attached to the model. You could check by putting a dd as the very first line in the bootFreezeIfAttachedToToken method:

public static function bootFreezeIfAttachedToToken(): void
{
    dd('here?');
}

If that doesn’t halt the application, then it’s not being called.

Please or to participate in this conversation.