- How do I generate sequential references like 'ORD-2024-001' for Laravel models?
- Use the template-based strategy by defining a format like `{PREFIX}-{YEAR}-{SEQ}` in your model’s `$referenceFormat` property. The package auto-increments the sequence per tenant or globally, with optional daily/monthly/yearly resets. Example: `protected $referenceFormat = 'ORD-{YEAR}-{SEQ:03}';`
- Does this package work with Laravel 13 and PHP 8.2+?
- Yes, the package is fully compatible with Laravel 10–13 and requires PHP 8.1+. It leverages modern Laravel features like traits, migrations, and Artisan commands without breaking changes. Always check the [GitHub releases](https://github.com/EG-Mohamed/Referenceable/releases) for the latest version.
- Can I use this for multi-tenant SaaS apps where each tenant needs isolated reference sequences?
- Absolutely. The package includes tenant-aware scopes by default. Configure the `tenant_column` in your model or global config (e.g., `tenant_column = 'company_id'`), and sequences will auto-isolate per tenant. Example: `protected $tenantColumn = 'company_id';`
- What happens if two references collide during high-concurrency writes?
- The package handles collisions automatically with a retry mechanism. Configure `max_retries` in your model or global config (default: 3). For extreme loads, use the `generateReference()` method with a custom retry logic or batch processing via `generateBatch()`.
- How do I customize reference formats like 'INV-{YEAR}{SEQ:04}' with placeholders?
- Define the `$referenceFormat` property in your model using placeholders: `{YEAR}`, `{MONTH}`, `{SEQ}`, `{RANDOM}`, or `{MODEL}`. Example: `protected $referenceFormat = 'INV-{YEAR}{SEQ:04}'` generates `INV-20240001`. Placeholders like `{SEQ:03}` pad sequences with zeros. Full list in the [README](https://github.com/EG-Mohamed/Referenceable#template-system).
- Is there a performance impact for large-scale apps (e.g., 10K+ references/day)?
- The package is optimized for performance with caching, batch operations, and database transactions. For sequential strategies, use a dedicated `referenceable_sequences` table (auto-created during install). Benchmark with `generateBatch()` for bulk operations. Monitor query logs if using high-frequency writes.
- How do I test reference generation in PHPUnit/Pest without hitting the database?
- Mock the `HasReference` trait in unit tests. For Pest, use `fake()` to simulate deterministic references: `fake()->reference('ORD-{YEAR}-{SEQ}')`. For PHPUnit, extend the trait and override `generateReference()` to return hardcoded values. Example: `public function generateReference(): string { return 'TEST-123'; }`
- Can I migrate from manual reference logic (e.g., `order_id`) to this package?
- Yes, follow a phased approach: 1) Add the `reference` column to your models. 2) Backfill existing references via a migration. 3) Update APIs/controllers to use `$model->reference` instead of legacy IDs. 4) Deprecate old fields in API responses. Use `php artisan referenceable:backfill` for bulk reference generation.
- Are there alternatives to this package for simpler reference needs?
- For basic needs, consider `spatie/laravel-activitylog` (for audit trails) or `laravel-ide-helper` (for static references). However, this package uniquely combines sequential numbering, tenant isolation, and template flexibility. If you only need random references, `Str::random(10)` works, but lacks collision handling and customization.
- How do I handle reference changes (e.g., updating an invoice reference from 'INV-001' to 'INV-2024-001')?
- Use the `regenerateReference()` method to update references while preserving uniqueness. For critical models, log old references in an `audit_logs` table before updating. Example: `$invoice->regenerateReference(); $invoice->save();`. Configure `immutable` in your model to prevent updates if needed.