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

Fiton012's avatar

Override eloquent's save method on pivot table

I have three tables: Products, Categories and a pivot one CategoryProduct.

I have an attribute updated_by and I want this to be automatically set to Auth::id() upon all create/update requests.

So far I am able to save data by using the sync() method ie.

$categoriesArray = [ 
    1 => ['updated_by' => Auth::id()],
    2 => ['updated_by' => Auth::id()],
    ...
];
$product->categories()->sync($categoriesArray); 

I want to simplify the above by overriding the save method on CategoryProduct model ie.

class CategoryProduct extends Model
{

    protected $table = 'category_product';
    protected $fillable = ['product_id', 'category_id', 'created_by', 'updated_by'];

    public function save(array $options = array())
    {
        $this->updated_by = $this->updated_by ?: Auth::id();

        parent::save($options);
    }
}

So that I can save my categories like so:

$categoriesArray = [1, 2, 3];
$product->categories()->sync($categoriesArray); 

However for some reason the save method is not triggered upon saving resulting in a MySQL error. General error: 1364 Field 'updated_by' doesn't have a default value.

Any ideas?

0 likes
4 replies
martinbean's avatar
Level 80

@alexandros@hobbii.com Don’t override core Eloquent methods. Use an event or observer instead.

You also need to wary about trying to access an authenticated user in contexts other than a HTTP request. For example, calling Auth::id() is not going to work in a console command or queued job where there isn’t the notion of an authenticated user.

1 like
Fiton012's avatar

Thanks for the reply @martinbean. Observer works great when saving a Product (using a ProductObserver) or a Category (using a CategoryObserver) however when I am using

$product->categories()->sync($categoriesArray); 

The ProductCategoryObserver is not triggered. Why is this happening?

martinbean's avatar

Because a category isn’t being updated; rows are being synced to an intermediary table.

Events aren’t dispatched for that because there could be hundreds of them being synced.

Fiton012's avatar

Ok so I guess in that case using the below pattern is unavoidable, right?

$categoriesArray = [ 
    1 => ['updated_by' => Auth::id()],
    2 => ['updated_by' => Auth::id()],
    ...
];
$product->categories()->sync($categoriesArray); 

Please or to participate in this conversation.