Use this library to bind multiple key/value pair preferences to your application's Eloquent models. Preferences are stored in your application's database so they can be easily stored and queried for. This library supports Eloquent 5 through 8 installed either standalone or as a part of the full Laravel framework. Issues and pull requests are welcome! See CONTRIBUTING.md for more information.
Run composer require klaude/eloquent-preferences
to download and install the library.
- Add
EloquentPreferencesServiceProvider
toconfig/app.php
:
// ...
return [
// ...
'providers' => [
// ...
KLaude\EloquentPreferences\EloquentPreferencesServiceProvider::class,
],
// ...
];
- Install the configuration and database migration files:
$ php artisan vendor:publish
-
Model preferences are stored in the "model_preferences" database table by default. If you would like to use a different table then edit the "table" entry in
config/eloquent-preferences.php
. -
Install the model preferences database:
$ php artisan migrate
-
Model preferences are stored in the "model_preferences" database table by default. If you would like to use a different table then define the
MODEL_PREFERENCE_TABLE
constant at your project's point of entry with your preferred table name. -
Install the model preferences database. There are a number of ways to do this outside of Laravel. Here's the schema blueprint to apply:
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use KLaude\EloquentPreferences\Preference;
// ...
Model::getConnectionResolver()
->connection()
->getSchemaBuilder()
->create((new Preference)->getQualifiedTableName(), function (Blueprint $table) {
$table->increments('id');
$table->string('preference');
$table->string('value');
$table->morphs('preferable');
$table->timestamps();
});
Add the HasPreferences
trait to the Eloquent models that you would like to have related preferences.
use KLaude\EloquentPreferences\HasPreferences;
// ...
class MyModel extends Model
{
use HasPreferences;
// ...
}
This builds a polymorphic has-many relationship called "preferences" that you can query on your model like any other Eloquent relationship. Model preferences are modeled in the KLaude\EloquentPreferences\Preference
class. A preference object has preference
, value
, and Eloquent's built-in created_at
and updated_at
attributes. The HasPreferences
trait can be used by any number of model classes in your application.
// Retrieving preferences via Eloquent
/** @var KLaude\EloquentPreferences\Preference $myPreference */
$myPreference = MyModel::find($someId)->preferences()->where('preference', 'my-preference')->get();
// Saving preferences via Eloquent
$preference = new Preference;
$preference->preference = 'some preference';
$preference->value = 'some value';
$myModel->preferences()->save($preference);
Eloquent queries can be run directly on the Preference
class as well.
/** @var Illuminate\Database\Eloquent\Collection|KLaude\EloquentPreferences\Preference[] $preferences */
$preferences = Preference::whereIn('preference', ['foo', 'bar'])->orderBy('created_at')->get();
The HasPreferences
trait has a number of helper methods to make preference management a little easier.
Call the getPreference($preferenceName)
or prefers($preferenceName)
methods to retrieve that preference's value.
$numberOfFoos = $myModel->getPreference('number-of-foos');
$myModel->prefers('Star Trek over Star Wars') ? liveLongAndProsper() : theForceIsWithYou();
Call the setPreference($name, $value)
or setPreferences($arrayOfNamesAndValues)
methods to set your model's preference values. Setting a preference either creates a new preference row if the preference doesn't exist or updates the existing preference with the new value.
$myModel->setPreference('foo', 'bar');
$myModel->setPreferences([
'foo' => 'bar',
'bar' => 'baz',
]);
Call the clearPreference($preferenceName)
, clearPreferences($arrayOfPreferenceNames)
, or clearAllPreferences()
methods to remove one, many, or all preferences from a model. Clearing preferences removes their associated rows from the preferences table.
$myModel->clearPreference('some preference');
$myModel->clearPreferences(['some preference', 'some other preference']);
$myModel->clearAllPreferences();
By default, getPreference()
and prefers()
return null
if the preference is not stored in the database. There are two ways to declare default preference values:
- Use an optional second parameter to
getPreference()
andprefers()
to define a default value per call. If the preference is not stored in the database then the default value is returned.
// $myPreference = 'some default value'
$myPreference = $myModel->getPreference('unknown preference', 'some default value');
- Avoid requiring extra parameters to every
getPreference()
andprefers()
call by declaring a protected$preference_defaults
array in your model containing a key/value pair of preference names and their default values. If the preference is not stored in the database but is defined in$preference_defaults
then the value in$preference_defaults
is returned. If neither of these exist then optional default value parameter ornull
is returned.
class MyModel extends Model
{
use HasPreferences;
// ...
protected $preference_defaults = [
'my-default-preference' => 'my-default-value',
];
}
// ...
// $myPreference = 'my-default-value'
$myPreference = $myModel->getPreference('my-default-preference');
// $myPreference = 'fallback value'
$myPreference = $myModel->getPreference('my-unstored-preference', 'fallback value');
Please note default preference values only apply when using the getPreference()
and prefers()
methods. Default values are not honored when retrieving preferences by Eloquent query.
Preferences are stored as strings in the database, but can be cast to different types when retrieved.
Declare a protected $preference_casts
array in your model containing a key/value pair of preference names and the types to cast their values to. Preferences are stored and cast according to the same rules as Eloquent's attribute type casts.
class MyModel extends Model
{
use HasPreferences;
// ...
protected $preference_casts = [
'boolean-preference' => 'boolean',
'floating-point-preference' => 'float',
'date-preference' => 'date',
];
}
As with default values, casting preferences is only performed when using the getPreference()
, prefers()
, setPreference()
, and setPreferences()
helper methods.
Hidden Preference Attributes
By default all preference model attributes are visible when exporting to JSON. However it is possible to declare hidden attributes that act in the same manner as Eloquent's hidden attributes. There are two ways to declare which preference attributes to hide from JSON export:
- If this library is being used in a Laravel project then declare hidden attributes in the "hidden-attributes" key in
config/eloquent-preferences.php
.
return [
// ...
'hidden-attributes' => ['created_at', 'updated_at'],
// ...
];
- If this library is being used outside the Laravel framework then define the
MODEL_PREFERENCE_HIDDEN_ATTRIBUTES
constant at your project's point of entry with a comma-separated list of attributes to hide from JSON export.
const MODEL_PREFERENCE_HIDDEN_ATTRIBUTES = 'created_at,updated_at';