---
title: "Defining options — Options for Laravel | Roundly"
description: "Extend BaseOption to declare an option’s key, default, cast, encryption, rules and presentation — or scaffold one with make:option."
url: https://roundly-consulting.com/open-source/docs/options-for-laravel/defining-options
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Options for Laravel](https://roundly-consulting.com/open-source/docs/options-for-laravel.md)

# Defining options

Every option is a small class extending BaseOption. With no overrides, the key is the class basename, the value casts to string and the default is null:

```php
use RoundlyConsulting\Options\BaseOption;

final class SimpleOption extends BaseOption
{
    // Uses all defaults: key 'SimpleOption', cast 'string', default null.
}
```

Override the hooks to customise it — key(), default(), castAs(), encrypted(), rules(), authorizeRead() / authorizeWrite() and the presentation methods label(), help(), section() and order():

```php
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use RoundlyConsulting\Options\BaseOption;

final class NotificationPreferences extends BaseOption
{
    public function key(): string
    {
        return 'notification-preferences';
    }

    public function default(): mixed
    {
        return collect(['email' => true, 'sms' => false]);
    }

    public function castAs(): string|CastsAttributes
    {
        return 'collection';
    }
}
```

The examples throughout these docs use a ThemeOption like this one:

```php
namespace App\Options;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use RoundlyConsulting\Options\BaseOption;

final class ThemeOption extends BaseOption
{
    public function key(): string
    {
        return 'theme';
    }

    public function default(): mixed
    {
        return 'light';
    }

    public function castAs(): string|CastsAttributes
    {
        return 'string';
    }
}
```

## What you can override

| Method | Default | Purpose |
| --- | --- | --- |
| `key(): string` | class basename | The storage key — unique per option. |
| `default(): mixed` | null | Returned when nothing is stored for the scope. |
| `castAs(): string\|CastsAttributes` | 'string' | How the stored value is cast on read and write. |
| `encrypted(): bool` | false | Encrypt the value at rest. |
| `rules(): array\|string` | \[\] | Laravel validation rules applied on set(). |
| `readable(): string` | title-cased key | Human name — notification-preferences becomes Notification Preferences. Used by options:list. |
| `label(): string` | readable() | Field label in a group definition. |
| `help(): ?string` | null | Help text under the field. |
| `section(): ?string` | null | Section or tab a UI may group the field under. |
| `order(): int` | 0 | Sort order within a group (ascending). |
| `authorizeRead(?Authenticatable, ?Model): bool` | true | Read hook, enforced when authorization is enabled. |
| `authorizeWrite(?Authenticatable, ?Model): bool` | true | Write hook, enforced when authorization is enabled. |

label(), help(), section() and order() are documented by the optional HasPresentation contract, authorizeRead() and authorizeWrite() by AuthorizesOptions. BaseOption already implements both sets, so implementing the contracts is never required.

## Generating options

make:option scaffolds a class in app/Options. --key and --cast fill in the key and cast, --encrypted turns encryption on, and --enum switches to a stub that casts through EnumCast:

```bash
php artisan make:option ThemeOption --cast=string --key=theme
php artisan make:option SecretToken --encrypted
php artisan make:option StatusOption --enum="App\Enums\Status"
```

## Using an option class directly

Each option also works on its own — make() for the global scope, for() for an owner. This is shorthand, not a separate path: value(), set(), has(), forget(), reset() and remember() are final and run through the same OptionsManager as the facade, so they behave identically and Options::fake() sees them:

```php
ThemeOption::make()->value();          // global value, or default() when unset
ThemeOption::make()->set('dark');      // global write

ThemeOption::for($user)->value();      // owner-scoped read
ThemeOption::for($user)->set('light'); // owner-scoped write
ThemeOption::for($user)->has();
ThemeOption::for($user)->forget();
```

## 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](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## 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.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/options-for-laravel.md)
