r94ever/laravel-model-setting
r94ever/laravel-model-setting lets Laravel Eloquent models carry their own flexible key-value settings. Add the trait, then store and retrieve per-model configuration through a simple API, avoiding extra boilerplate while keeping settings close to the models that use them.
Install the package and its dependencies:
composer require <vendor>/<package>:^1.0
Publish and run the migration (settings are persisted, so the schema matters):
php artisan vendor:publish --tag=<package>-migrations
php artisan migrate
Publish the config file if the package ships one:
php artisan vendor:publish --tag=<package>-config
Where to look first, in this order:
config/<package>.php — table name, model class, cache toggle, default values.whereSetting() scope can efficiently filter on.First use case — read a setting, then query rows by it:
// Store
Setting::set('billing.currency', 'EUR');
// Read
$currency = Setting::get('billing.currency', 'USD');
// Query rows scoped by a setting
$users = User::whereSetting('billing.currency', 'EUR')->get();
The whereSetting() scope is the natural entry point for filtering any model that uses the package's trait — start here to validate your install end to end.
Upgrading from 1.0.0: 1.0.1 is a patch release that fixes the
whereSetting()scope method. If you adopted 1.0.0, bump to^1.0.1and re-run your test suite against any query that uses the scope before shipping. There are no breaking changes or deprecations in this release, so the upgrade is low risk — but do not assume the scope worked on 1.0.0, as it may have been silently returning incorrect results.
Scope composition. whereSetting() is a query scope, so it composes with the rest of the builder. Treat it as one predicate among many rather than a standalone query entry point:
$active = User::query()
->where('is_active', true)
->whereSetting('notifications.email', true)
->orderBy('created_at')
->paginate(50);
Chaining multiple settings. Because each call adds a constraint, multiple whereSetting() calls compose with AND semantics. For OR logic, wrap in a closure:
User::where(function ($q) {
$q->whereSetting('tier', 'pro')
->orWhereSetting('tier', 'enterprise');
})->get();
Scoping related models. The scope applies to the model that uses the trait. To filter a relation, apply it inside the relationship constraint:
$teams = Team::with(['users' => fn ($q) => $q->whereSetting('notifications.email', true)])->get();
Default-on-create. Prefer a model observer or the package's default-values config over scattering Setting::set() calls through controllers. Keeping defaults in config makes local/test environments reproducible.
Testing. Use RefreshDatabase and assert on the scope directly — the 1.0.1 fix is specifically about scope behavior, so a regression test pinning your expected semantics is cheap insurance:
public function test_where_setting_filters_correctly(): void
{
User::factory()->create();
User::factory()->create();
User::first()->setSetting('tier', 'pro');
$this->assertCount(1, User::whereSetting('tier', 'pro')->get());
}
Seeding. Seed settings in a dedicated seeder rather than in migrations, so production deploys and test refreshes stay separate concerns.
whereSetting() was broken in 1.0.0. Any tests or queries written against 1.0.0 may have been passing while asserting the wrong behavior — re-read those assertions rather than just re-running them.where clauses. whereSetting('enabled', true) may not match a stored "1" on every driver. Normalize on write, or cast explicitly in the query, and add a test for each type you rely on.Setting::set() should bust it.billing.currency, dotted lowercase) early; mixed conventions are the most common source of "setting not found" bugs.whereSetting() is not available on a model, the trait is missing from that model — a BadMethodCallException here is a trait problem, not a package problem.^1.0.1 rather than ^1.0 in composer.json so you do not silently resolve back to a 1.0.0 lockfile on a fresh install.whereSetting() combined with orWhere groups, whereHas, or soft-deleted models — is the most likely place to find remaining rough edges.How can I help you explore Laravel packages today?