eg-mohamed/referenceable
Laravel package that adds reference numbers to Eloquent models with configurable formats. Supports random, sequential, and template-based generation (e.g., year/month/seq/random), collision handling, validation, and tenant-aware sequences. Includes install command, config publishing, and Laravel 10–...
composer require eg-mohamed/referenceable
php artisan referenceable:install
Schema::create('orders', function (Blueprint $table) {
$table->string('reference')->unique()->index();
// ...
});
use MohamedSaid\Referenceable\Traits\HasReference;
class Order extends Model
{
use HasReference;
}
$order = Order::create(['customer_id' => 1]);
echo $order->reference; // e.g., "ORD-123456"
protected $referenceStrategy (random, sequential, template) and its corresponding options.php artisan referenceable to explore available commands.{PREFIX}, {SEQ}, {YEAR}, etc., for template-based generation.Model Integration:
protected $referenceStrategy = 'random' for simple alphanumeric references.protected $referenceStrategy = 'sequential';
protected $referenceSequential = [
'start' => 1000,
'reset_frequency' => 'monthly',
];
protected $referenceStrategy = 'template';
protected $referenceTemplate = [
'format' => '{PREFIX}{YEAR}{SEQ}',
'sequence_length' => 4,
];
Batch Operations:
php artisan referenceable:generate App\Models\Order --batch=500
php artisan referenceable:validate App\Models\Order --fix
Querying:
$orders = Order::referenceStartsWith('ORD-2024')->get();
$order = Order::findByReference('ORD-123456');
Multi-Tenancy:
protected $referenceUniquenessScope = 'tenant';
protected $referenceTenantColumn = 'company_id';
Schema::table('orders', function (Blueprint $table) {
$table->index('reference');
});
use MohamedSaid\Referenceable\Rules\ValidReference;
$request->validate([
'reference' => ['required', new ValidReference(Order::class)],
]);
Order::created(function ($order) {
logger()->info("Generated reference: {$order->reference}");
});
Collision Handling:
retry strategy may cause delays if references are highly constrained. Monitor referenceMaxRetries and consider append for high-volume systems.referenceMaxRetries or switch to append in config/referenceable.php:
'collision_strategy' => 'append',
Sequential Resets:
reset_frequency (e.g., monthly) resets counters at midnight. Test edge cases (e.g., records created at 23:59 vs 00:01).never for global sequences or adjust start values to avoid overlaps.Template Placeholders:
{SEQ} in template strategy shares the same counter as sequential strategy. Overlaps can occur if both are used.Performance:
generateBatch) may lock tables. Use --batch to control concurrency.batch_size in config/referenceable.php:
'batch_size' => 100,
Caching:
cache_config improves performance but may cause stale configurations during deployments.php artisan config:clear
--dry-run to preview changes:
php artisan referenceable:generate App\Models\Order --dry-run
php artisan referenceable:stats App\Models\Order --json
config/referenceable.php:
'debug' => env('APP_DEBUG', false),
Custom Strategies:
MohamedSaid\Referenceable\Strategies\StrategyInterface to create custom generators (e.g., UUID-based or hash-based).config/referenceable.php:
'strategies' => [
'custom' => \App\Strategies\CustomReferenceStrategy::class,
],
Dynamic Configuration:
public function getReferencePrefixAttribute()
{
return $this->isPremium() ? 'PREM-' : 'ORD-';
}
Validation Rules:
ValidReference rule for custom logic:
use MohamedSaid\Referenceable\Rules\ValidReference as BaseValidReference;
class CustomValidReference extends BaseValidReference
{
public function passes($attribute, $value)
{
return parent::passes($attribute, $value) &&
str_contains($value, 'VALID');
}
}
Counter Management:
ModelReference service:
$modelReference = app(\MohamedSaid\Referenceable\ModelReference::class);
$modelReference->resetCounter(Order::class);
config('referenceable.strategy') to check defaults.referenceCase affects output but not uniqueness checks. Ensure case-insensitive indexes if needed:
Schema::table('orders', function (Blueprint $table) {
$table->index('reference', 'idx_reference_lower');
});
referenceCharacters may break validation patterns. Test thoroughly with edge cases (e.g., special characters).How can I help you explore Laravel packages today?