Owners & the HasOptions trait
Any Eloquent model can own option values. Pass it as the owner argument, or start with Options::for():
use RoundlyConsulting\Options\Facades\Options;
Options::set(LocaleOption::class, 'sk', $team);
Options::get(LocaleOption::class, $team); // 'sk'
Options::get(LocaleOption::class); // the global value — untouched
Options::for($tenant)->set(ThemeOption::class, 'dark');
Options::for($tenant)->get(ThemeOption::class); // 'dark'The HasOptions trait
Add HasOptions to a model to resolve options bound to it:
use RoundlyConsulting\Options\Traits\HasOptions;
final class User extends Authenticatable
{
use HasOptions;
}
$user->option(ThemeOption::class)->value(); // this user’s value, or the default
$user->option(ThemeOption::class)->set('dark');
$user->option('theme')->value(); // a registered key works toooption() returns the option instance scoped to that model, so value(), set(), has(), forget() and remember() all act on the model’s own row. It accepts a class-string or a registered key. The trait is sugar over the same manager — $user->option(ThemeOption::class)->set('dark') is exactly Options::set(ThemeOption::class, 'dark', $user), fake included.
How scopes stay isolated
Rows are matched on owner_type — the model’s morph class, so morph-map aliases apply — and owner_id. Cache entries are fingerprinted the same way, so one user’s value never leaks into another user’s scope or the global one.
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 cryptoBy 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.