secretwebmaster/laravel-optionable

Allow any Eloquent model to have own options such as user options, page options, etc.

v1.3.1 2025-09-07 05:45 UTC

This package is auto-updated.

Last update: 2025-09-07 05:46:25 UTC


README

Allow any Eloquent model to have flexible options (like user settings, page options, metadata, etc.).
Options are stored in a dedicated table and can be retrieved, updated, or deleted easily.

Installation

Install via Composer:

composer require secretwebmaster/laravel-optionable

Run the migration to create the options table:

php artisan migrate

That’s all you need 🎉

Overview

Usage

Add the HasOptions trait to any Eloquent model. Example: Post model

use Illuminate\Database\Eloquent\Model;
use Secretwebmaster\LaravelOptionable\Traits\HasOptions;

class Post extends Model
{
    use HasOptions;  // <-- add this

    //...
}

Now you can manage options directly on the model instance:

$post = Post::first();

Get all options

$post->getOptions(); // default: array
$post->getOptions('json'); // return JSON
$post->getOptions('collection'); // return Collection

Get single option value

$post->getOption('key');

With fallback:

$post->getOption('key', 'default');

If you want to allow null/empty values (instead of fallback):

$post->getOption('key', 'default', false);

Set single option

$post->setOption('key', 'value');
$post->setOption('theme', ['color' => 'blue']); // arrays/objects supported (stored as JSON)

Set multiple options

$post->setOptions([
    'language' => 'English',
    'mode' => 'dark',
    'homepage' => 'welcome',
]);

Delete single option

$post->deleteOption('key');

Delete multiple options

$post->deleteOptions(['key1', 'key2']);

Delete all options

$post->deleteAllOptions();

Or keep some keys:

$post->deleteAllOptions(['language']); // deletes everything except 'language'

Legacy Support

For backward compatibility, all methods are also available in snake_case:

$post->get_option('key');
$post->set_option('key', 'value');
$post->delete_all_options();

Both camelCase and snake_case will work ✅

Table Schema

The migration creates an options table with:

  • id
  • key (string)
  • value (json, nullable)
  • optionable_type (string)
  • optionable_id (unsignedBigInteger)
  • timestamps

Constraints & Indexes:

  • Unique per model: optionable_type + optionable_id + key
  • Indexed key column
  • Indexed polymorphic relation via morphs()

License

MIT © secretwebmaster