Skip to content

Instantly share code, notes, and snippets.

@squatto
Last active December 24, 2022 22:52
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save squatto/4b8c541c2c8f6bce700bc0f700cb34ac to your computer and use it in GitHub Desktop.
Save squatto/4b8c541c2c8f6bce700bc0f700cb34ac to your computer and use it in GitHub Desktop.
CanSaveQuietly Laravel model trait - save or update models without firing any model events

To use, add the trait to your project and then add the CanSaveQuietly trait to your model:

Make sure to change the namespace of the trait to match your project's structure!

class Product extends Model
{
    use CanSaveQuietly;

    // ...
}

Then you can save or update your model instance without firing any model events:

/**
 * @param OrderDeskItem $item
 * @param Product $product
 */
protected function associateItemToProduct(OrderDeskItem $item, Product $product): void
{
    $product->updateQuietly([
        'order_desk_inventory_item_id'          => $item->id,
        'order_desk_inventory_item_assigned_at' => now(),
        'order_desk_inventory_item_updated_at'  => now(),
    ]);
}

This is particularly useful in situations where you have a model event listener that results in the model being saved/updated. If you allow model events to fire then you'll end up in an endless loop.

For example, in EventServiceProvider:

protected $listen = [
    ProductUpdated::class => [
        UpdateItemOnOrderDesk::class,
    ],
];

And in the UpdateItemOnOrderDesk listener:

$product->update([
    'order_desk_inventory_item_id' => $item->id,
]);

Doing this would cause the ProductUpdated event to fire, which fires the UpdateItemOnOrderDesk listener, which calls $product->update() again, which fires the ProductUpdated event again, and so on.

By instead doing it this way:

$product->updateSilently([
    'order_desk_inventory_item_id' => $item->id,
]);

You avoid causing the ProductUpdated event to fire again.

<?php
namespace App\Models\Traits;
/**
* @mixin \Eloquent
*/
trait CanSaveQuietly
{
/**
* Save the model without firing any model events
*
* @param array $options
*
* @return mixed
*/
public function saveQuietly(array $options = [])
{
return static::withoutEvents(function () use ($options) {
return $this->save($options);
});
}
/**
* Update the model without firing any model events
*
* @param array $attributes
* @param array $options
*
* @return mixed
*/
public function updateQuietly(array $attributes = [], array $options = [])
{
return static::withoutEvents(function () use ($attributes, $options) {
return $this->update($attributes, $options);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment