A Laravel package to enforce automatic generation of unique attribute values for Eloquent models, making it easy to maintain uniqueness without manual intervention.
- Automatically generate unique attribute values for Eloquent models.
- Customizable formats (
numerify
,lexify
, or mixed patterns). - Flexible configuration for prefixes, suffixes, separators, and retries.
- Supports models with soft deletes.
- Fully customizable events for enforcing and notifying unique attribute changes.
Managing unique attributes in Eloquent models often involves tedious logic, especially when combining custom formats and real-time checks. This package provides an automatic, extensible solution. It ensures attributes are unique within the database and adhere to defined configurations.
Install the package using Composer:
composer require cndrsdrmn/eloquent-unique-attributes
To customize the default behavior, publish the configuration file:
php artisan vendor:publish --tag=unique-attributes-config
This will create a config/unique_attributes.php
file:
return [
/**
* The prefix to add to the beginning of the generated unique value.
*/
'prefix' => '',
/**
* The suffix to add to the end of the generated unique value.
*/
'suffix' => '',
/**
* The separator to use between prefix, value, and suffix.
*/
'separator' => '_',
/**
* The maximum number of retries to generate a unique value before increasing the length.
*/
'max_retries' => 100,
/**
* The default length of the generated unique value.
*/
'length' => 8,
/**
* The format of the unique value.
*
* Supported options:
* - `numerify` - Replace `#` with random digits.
* - `lexify` - Replace `?` with random letters.
* - `bothify` - Replace `#` with digits and `?` with letters.
*
* @see https://github.com/cndrsdrmn/php-string-formatter
*/
'format' => 'bothify',
];
prefix
: A string prepended to the generated value.suffix
: A string appended to the generated value.separator
: A separator betweenprefix
,value
, andsuffix
.max_retries
: Maximum attempts to generate a unique value before increasing length.length
: The initial length of the generated unique value.format
: Determines the type of value (numerify
for digits,lexify
for letters,botify
for mixed).
Include the HasEnforcesUniqueAttributes
trait in any Eloquent model requiring unique attributes:
namespace App\Models;
use Cndrsdrmn\EloquentUniqueAttributes\HasEnforcesUniqueAttributes;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasEnforcesUniqueAttributes;
/**
* Define the unique attributes configuration.
*/
public function enforcedUniqueColumns(): array
{
return [
'barcode' => ['format' => 'numerify', 'separator' => '-'],
'sku' => ['prefix' => 'SKU', 'length' => 10],
];
}
}
When creating the model, the unique values will automatically be enforced:
$product = Product::create([
'name' => 'Sample Product',
]);
echo $product->sku; // Example: SKU_1234567890
This package fires events during the unique value generation process:
eloquent.enforcing
: Fired before generating unique attributes. If a listener returns a value, the process of enforcing unique attributes is skipped.eloquent.enforced
: After unique attributes are generated.
You can listen to these events in your application to implement custom logic:
use Illuminate\Support\Facades\Event;
Event::listen('eloquent.enforcing: App\Models\Product', function ($model, $event) {
// Returning any value here will skip the enforcement of unique attributes.
return true;
});
Event::listen('eloquent.enforced: App\Models\Product', function ($model, $status) {
// Execute logic after unique attributes are enforced.
if ($status) {
Log::info('Unique attributes enforced for model', ['model' => $model]);
}
});
Note: If a listener for the
eloquent.enforcing
event returns a value (truthy or falsy), the unique attribute generation process will be skipped for the current model.
This package includes PHPUnit tests. To run the tests, use the following command:
composer test
We welcome contributions! Follow these steps to contribute:
- Fork the repository.
- Create a new branch (
git checkout -b feature-name
). - Commit your changes (
git commit -m "Add new feature"
). - Push to the branch (
git push origin feature-name
). - Open a Pull Request.
This package is open-source software licensed under the MIT license.