Skip to main content

← Payload Casts · Back to README · Development →

API Reference

HasSettings trait​

MethodReturnsPurpose
settings()SettingsServiceAccess effective settings for this model
defaultSettings()SettingsServiceAccess shared defaults for this model class
modelSettings()Eloquent RelationLoad defaults and overrides as a relation

Use the modelSettings relation only for with(), load(), or loadMissing() and as the resulting loaded property. Do not use its relation query as an alternative read or CRUD API. Use the two service methods to read or mutate values. At runtime, the relation is a package SettingsRelation based on Laravel's MorphMany relation.

SettingsService​

MethodReturnsBehavior
all()CollectionReturns defaults merged with model overrides
get(int|string|UnitEnum $key)mixedReturns an override, its default, or null
has(int|string|UnitEnum $key)boolReports whether an effective key exists, including stored null
set(int|string|UnitEnum $key, mixed $value)voidCreates or replaces a setting with the exact JSON value
setMany(iterable $values)voidUpserts every value in one bounded transactional batch
forget(int|string|UnitEnum $key)voidRemoves a setting if it exists
forgetMany(iterable $keys)voidRemoves the listed keys from the current scope
purge()voidRemoves every setting stored in the current scope

The keyed methods accept backed and pure unit enums. Laravel converts backed enums to their backing value and pure unit enums to their case name.

SettingsService has no caller-supplied fallback parameter on get(). Use has($key) to distinguish a missing effective key from a stored JSON null.

Resolution matrix​

Model overrideClass defaultget() resulthas() resultIncluded by all()
PresentPresentOverride, including nulltrueOverride
PresentMissingOverride, including nulltrueOverride
MissingPresentDefault, including nulltrueDefault
MissingMissingnullfalseNo entry

For an unsaved model, get() returns null, has() returns false, and all() returns an empty collection. Class defaults are only inherited by persisted models.

all​

$settings = $user->settings()->all();

$timezone = $settings->get('timezone');

The result is an Illuminate\Support\Collection keyed by setting key. For model settings, overrides replace defaults with the same key.

get​

$timezone = $user->settings()->get('timezone');

The result is the effective decoded or cast value. A missing override falls back to the default. A missing override and default returns null. The signature intentionally accepts no second fallback argument.

has​

$hasTimezone = $user->settings()->has('timezone');

The method returns true when either the model override or class default row exists. A stored JSON null returns true; a missing key returns false. Lazy and eager-loaded services use the same precedence, and the eager path performs no additional settings query.

set​

$user->settings()->set('timezone', 'Europe/Paris');

The method validates the owner and normalized key, then uses an update-or-create operation for the model type, model identifier, scope discriminator, and key. Every JSON value is stored, including null, empty strings, whitespace strings, empty arrays, zero, and false. After a successful write, the loaded modelSettings relation is cleared so the next read cannot reuse stale data.

setMany​

$user->settings()->setMany([
'timezone' => 'Europe/Paris',
'locale' => 'fr',
'obsolete' => null,
]);

The iterable keys use the same normalization as set(). If multiple input keys normalize to the same string, the last value wins. Every value uses one database-native upsert inside a transaction. The method validates the owner before consuming the iterable and clears modelSettings once after success. Use forgetMany() for deletion.

forget​

$user->settings()->forget('timezone');

For a valid owner, the method is safe when the key does not exist. Removing an override does not remove its shared default. The loaded relation is cleared after the delete.

forgetMany​

$user->settings()->forgetMany(['timezone', 'locale']);

The method normalizes and de-duplicates the iterable, then removes only those keys from the current scope with one delete. Missing keys have no effect. It returns void and clears the loaded relation after a successful call, including an empty iterable.

purge​

$user->settings()->purge();

For settings(), the method deletes every override belonging to that saved owner. It never deletes class defaults or another owner's overrides. For defaultSettings(), it deletes every default for that model class and leaves model overrides intact. It returns void and clears a loaded relation after success.

defaultSettings​

The service returned by defaultSettings() has the same eight methods:

$defaults = (new User)->defaultSettings();

$defaults->set('timezone', 'UTC');
$defaults->setMany(['timezone' => 'UTC', 'locale' => 'en']);
$timezone = $defaults->get('timezone');
$hasTimezone = $defaults->has('timezone');
$all = $defaults->all();
$defaults->forget('timezone');
$defaults->forgetMany(['timezone', 'locale']);
$defaults->purge();

Exceptions​

DragonCode\LaravelModelSettings\Exceptions\InvalidSettingsOwnerException extends PHP's DomainException. Every mutation through settings() throws it before a storage query when the owner model is unsaved, including an unsaved model with a preassigned key.

This validation also happens before a bulk iterable is consumed. Mutations through defaultSettings() remain valid because that service selects the class-default scope explicitly. Read-only access stays deterministic: an unsaved owner returns null or an empty collection without querying overrides, and has() returns false. A persisted owner with integer 0 or string '0' can read and mutate its model overrides; is_default keeps those rows separate from class defaults.

DragonCode\LaravelModelSettings\Exceptions\InvalidPayloadCast is thrown when a configured model-wide or key-aware cast is missing, has an invalid type, implements no supported contract, or cannot be resolved through the Laravel container. Its message may identify the parent model, setting key, and cast class, but never the payload.

DragonCode\LaravelModelSettings\Exceptions\InvalidSettingKey is thrown after normalization when a key is empty or contains only whitespace. Its message never contains the rejected key or payload.

DragonCode\LaravelModelSettings\Exceptions\BulkMutationException extends PHP's RuntimeException. Unexpected iterable, serialization, and persistence failures from setMany(), forgetMany(), and purge() are wrapped by this exception. Its message identifies the operation, owner class, and model or default scope without exposing setting keys or payloads. The original exception is available through getPrevious().

Existing package exceptions such as InvalidSettingsOwnerException, InvalidPayloadCast, and InvalidSettingKey are not wrapped. If a non-empty setMany() operation fails, the transaction rolls back its batch work and the existing loaded modelSettings relation is not cleared.

See Also​