Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Prefixed Ids Laravel Package

spatie/laravel-prefixed-ids

Generate friendly Stripe-like prefixed IDs for Laravel Eloquent models (e.g., user_xxx). Add a trait to models, create and store prefixed IDs, and resolve models from a prefixed ID via findByPrefixedId or automatic model detection.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-prefixed-ids
    

    Publish the config file:

    php artisan vendor:publish --provider="Spatie\PrefixedIds\PrefixedIdsServiceProvider"
    
  2. Configure Prefixes: Edit config/prefixed-ids.php to define prefixes for your models:

    'prefixes' => [
        'user' => \App\Models\User::class,
        'test_token' => \App\Models\TestToken::class,
    ],
    
  3. First Use Case: Generate a prefixed ID for a model:

    $user = new \App\Models\User();
    $user->prefixed_id = $user->getPrefixedId(); // Generates e.g., "user_fj39fj3lsmxlxl"
    $user->save();
    

Where to Look First

  • Config File: config/prefixed-ids.php (defines prefixes and model mappings).
  • Model Traits: HasPrefixedId trait (adds methods like getPrefixedId()).
  • Facade: PrefixedIds (for dynamic model resolution, e.g., getModelClass()).

Implementation Patterns

Workflows

  1. Model Integration: Use the HasPrefixedId trait in your Eloquent models:

    use Spatie\PrefixedIds\HasPrefixedId;
    
    class User extends Model
    {
        use HasPrefixedId;
    }
    
    • Automatically adds prefixed_id column (if not exists) and methods like getPrefixedId().
  2. Dynamic Prefix Resolution: Use the PrefixedIds facade to resolve models by prefixed IDs:

    $model = PrefixedIds::getModelClass('user_fj39fj3lsmxlxl'); // Returns \App\Models\User
    $instance = $model::findByPrefixedId('user_fj39fj3lsmxlxl');
    
  3. Custom Prefix Logic: Override getPrefixedId() in your model for custom logic:

    public function getPrefixedId(): string
    {
        return 'custom_' . $this->id;
    }
    
  4. API/URL-Friendly IDs: Use prefixed IDs in routes or APIs for clarity:

    Route::get('/users/{prefixed_id}', function ($prefixed_id) {
        return User::findByPrefixedId($prefixed_id);
    });
    

Integration Tips

  • Migrations: The package auto-creates the prefixed_id column if missing, but manually adding it ensures control:

    Schema::table('users', function (Blueprint $table) {
        $table->string('prefixed_id')->unique()->after('id');
    });
    
  • Seeding: Generate prefixed IDs in seeders:

    $user = new User();
    $user->prefixed_id = $user->getPrefixedId();
    $user->save();
    
  • Testing: Use findByPrefixedIdOrFail() to assert model existence:

    $this->assertEquals($user, User::findByPrefixedIdOrFail('user_fj39fj3lsmxlxl'));
    

Gotchas and Tips

Pitfalls

  1. Prefix Collisions: Avoid overlapping prefixes (e.g., user and users). Ensure uniqueness in config/prefixed-ids.php.

  2. Database Constraints: The prefixed_id column is set to unique by default. If you reuse IDs, handle conflicts in your logic:

    $user->prefixed_id = $user->getPrefixedId();
    if (User::where('prefixed_id', $user->prefixed_id)->exists()) {
        $user->prefixed_id .= '_duplicate';
    }
    
  3. Caching Prefixed IDs: If generating IDs in bulk (e.g., seeding), cache the PrefixedIds resolver to avoid repeated lookups:

    $resolver = app(Spatie\PrefixedIds\PrefixedIds::class);
    
  4. Legacy Systems: If migrating from auto-increment IDs, ensure prefixed_id is populated before queries:

    User::query()->update(['prefixed_id' => function ($query) {
        return $query->selectRaw('CONCAT("user_", id)');
    }]);
    

Debugging

  1. Invalid Prefixes: If findByPrefixedId() returns null, verify:

    • The prefix exists in config/prefixed-ids.php.
    • The model uses HasPrefixedId.
    • The prefixed_id column exists in the database.
  2. Custom Logic Errors: Overriding getPrefixedId() may break auto-generation. Test with:

    $this->assertStringStartsWith('custom_', $user->getPrefixedId());
    
  3. Performance: For large datasets, index the prefixed_id column:

    Schema::table('users', function (Blueprint $table) {
        $table->string('prefixed_id')->unique()->index();
    });
    

Extension Points

  1. Custom ID Generators: Extend the Spatie\PrefixedIds\IdGenerator class to support non-random IDs (e.g., UUIDs):

    class CustomIdGenerator extends IdGenerator
    {
        public function generate(): string
        {
            return Str::uuid()->toString();
        }
    }
    

    Register it in config/prefixed-ids.php:

    'id_generator' => \App\Services\CustomIdGenerator::class,
    
  2. Dynamic Prefixes: Use model observers or accessors to set prefixes dynamically:

    public function getPrefixedIdAttribute()
    {
        return $this->prefix . '_' . $this->id;
    }
    
  3. API Resources: Format prefixed IDs in API responses:

    public function toArray($request)
    {
        return [
            'id' => $this->prefixed_id,
            'name' => $this->name,
        ];
    }
    
  4. Soft Deletes: Ensure prefixed_id is included in deleted_at queries:

    User::withTrashed()->findByPrefixedId('user_fj39fj3lsmxlxl');
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport