NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Attributes for Laravel

Removing & syncing

Removals soft-delete by default; pass forceDelete: true to delete permanently:

use RoundlyConsulting\Attributes\Facades\Attributes;

Attributes::for($product)->forget('color');                           // soft delete; returns the count removed
Attributes::for($product)->forget(['color', 'size'], forceDelete: true); // permanently
Attributes::for($product)->forgetExcept(['color']);                   // list<string> of the removed names

The model methods are shorthand for forget() and forgetExcept() through the same manager:

$product->syncAttributeMeta('color', collect(['is_pretty' => 'yes']));

$product->detachAttribute('color');
$product->detachAttribute('color', forceDelete: true);
$product->detachAttributes(['color', 'size']);
$product->destroyAttributesExcept(['color']);
$product->destroyAttributes(['price']);

Syncing

sync() makes the model’s attributes match the given set exactly — attributes outside the set are removed, and each given value is attached or updated:

use RoundlyConsulting\Attributes\Facades\Attributes;

Attributes::for($product)->sync([
    'color' => 'black',
    'size'  => 'large',
]);                                                          // exactly color and size remain

Attributes::for($product)->sync(['color' => 'black'], forceDelete: true); // hard-delete the rest
Attributes::for($product)->sync(['color' => 'black'], meta: ['color' => ['hex' => '#000']]);
Attributes::for($product)->sync([]);                         // remove every attribute

$product->syncAttributes(['color' => 'black']);              // model shorthand

Behaviour reference

  • forget() — and detachAttribute(), detachAttributes(), destroyAttributes() — removes the named attributes and returns how many; AttributeDetached is dispatched once per name that was actually attached (a name that never was is a no-op), and with history enabled a detached revision is recorded.
  • forgetExcept() — and destroyAttributesExcept() — removes every attribute not in the keep-list through the same path, so each removal fires AttributeDetached and records a detached revision. It returns the removed names.
  • sync() — and syncAttributes() — validates every given value before anything is detached or written, then removes attributes outside the set the same way and attaches each value, all in one transaction, and dispatches AttributesSynced. It returns the attached Attribute models.
  • A force-deleting forgetExcept() or sync() also purges previously soft-deleted extras.
  • A soft-deleted value gives up its unique slot, so another owner can take it.

Soft-deleted attributes stay recoverable until attributes:prune removes them permanently (see Artisan commands). Attaching a name again after a soft delete restores its row with a fresh value and meta — the old meta is not revived.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.