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

Variable Keys Laravel Package

cline/variable-keys

Laravel Blueprint macros for variable primary key types, matching foreign keys, and polymorphic morph types. Easily switch between id/uuid/ulid (and more) via enums/config to keep migrations consistent across models and relationships.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Schema Flexibility: Aligns with Laravel’s evolving needs for non-integer primary keys (e.g., UUIDs for distributed systems, ULIDs for time-ordered data). The package’s enum-driven approach centralizes key-type decisions, reducing schema drift in microservices or modular monoliths.
  • Polymorphic Consistency: Resolves a pain point in Laravel’s polymorphic relationships (e.g., morphTo/morphWith) where key types (e.g., UUID vs. integer) historically required manual match logic or custom morph maps. The MorphType enum ensures alignment across tables.
  • Migration Hygiene: Eliminates repetitive switch/match blocks in migrations, improving readability and maintainability. Critical for teams with frequent schema changes or multi-developer workflows.
  • Configuration-Driven: Enables runtime key-type switching (e.g., via .env) without migration rewrites, supporting feature flags or A/B testing of key strategies (e.g., UUIDs for security vs. integers for performance).
  • Future-Proofing: Designed for Laravel’s Blueprint system, which is less likely to change than lower-level ORM APIs. Supports emerging use cases like composite keys or database-specific types (e.g., PostgreSQL’s UUID vs. MySQL’s CHAR(36)).

Integration Feasibility

  • Laravel 10+ Compatibility: Leverages PHP 8.4+ features (e.g., enums, union types) and Laravel’s Schema Builder, ensuring minimal friction with modern Laravel stacks. Backward compatibility with older versions would require polyfills.
  • Incremental Adoption: New tables can use variablePrimaryKey() without affecting existing migrations. Legacy tables may require retrofitting (e.g., adding UUID columns via Schema::table()).
  • ORM Synergy: Works with Eloquent’s key resolution (e.g., getKey(), getIncrementing()), but may need custom model bindings for legacy assumptions (e.g., Model::increment()). Polymorphic relationships benefit from built-in MorphType support.
  • Database Agnosticism: Abstracts key generation (e.g., UUIDs via ramsey/uuid), but assumes the underlying database supports the chosen type. PostgreSQL is ideal; MySQL/SQLite may need workarounds (e.g., CHAR(36) for UUIDs).
  • Testing Overhead: Requires validation of key-type generation, foreign key constraints, and polymorphic resolution across databases. CI pipelines must include multi-DB testing.

Technical Risk

  • Breaking Changes:
    • New macros (variablePrimaryKey(), variableForeignKey()) may conflict with custom Blueprint extensions or third-party packages modifying Blueprint (e.g., spatie/laravel-activitylog).
    • Polymorphic relationships with variable keys may expose edge cases in morphMap or MorphTo resolution.
  • Performance:
    • UUID/ULID generation adds overhead compared to auto-increment integers. Benchmarking required for high-write workloads (e.g., >10K writes/sec).
    • Foreign key constraints on non-integer types (e.g., UUIDs) may impact join performance in some databases.
  • Legacy Constraints:
    • Applications assuming integer keys (e.g., Model::find(1)) or ORM-specific features (e.g., Model::increment()) will need adjustments.
    • Third-party packages (e.g., spatie/laravel-permission) may not handle variable key types out of the box.
  • Migration Complexity:
    • Retrofitting existing tables (e.g., adding UUID columns) risks data integrity issues if not handled carefully.
    • Rollback scenarios for variable keys may require additional logic (e.g., dropping constraints safely).
  • Monitoring Gaps:
    • Key generation failures (e.g., UUID collisions) may not be surfaced by default. Custom logging/alerting may be needed.
    • No built-in observability for key-type usage patterns (e.g., tracking UUID vs. integer adoption).

Key Questions

  1. Key Strategy:
    • Will key types vary by model (e.g., UUIDs for users, integers for posts), or use a single type globally?
    • How will key collisions be mitigated (e.g., UUIDv7 timestamps vs. random UUIDs)?
  2. Migration Plan:
    • Are existing tables using integer PKs? How will backfills/retrofits be managed (e.g., Schema::table() vs. new columns)?
    • Will new tables adopt variable keys immediately, or incrementally?
  3. ORM Compatibility:
    • Does the application use custom model bindings or global scopes assuming integer keys?
    • Are there third-party packages (e.g., spatie/laravel-permission) that may conflict with variable key types?
  4. Performance:
    • What are the expected write volumes? Are UUIDs/ULIDs acceptable, or must integers be prioritized?
    • Will database indexing strategies (e.g., UUID hashing) be optimized?
  5. Polymorphic Dependencies:
    • Are there existing polymorphic relationships that must be preserved during migration?
    • How will morphMap be updated to reflect variable key types (e.g., userUser::class with UUID PK)?
  6. Monitoring:
    • How will key generation failures (e.g., UUID conflicts) be logged/alerted?
    • Are there tools (e.g., Laravel Telescope) to track key-type usage and performance?
  7. Database Support:
    • Which databases are in use (PostgreSQL, MySQL, SQLite)? Are UUIDs/ULIDs natively supported?
    • How will database-specific constraints (e.g., MySQL’s CHAR(36) for UUIDs) be handled?
  8. Testing:
    • Are there existing tests for migrations, polymorphic relationships, and foreign keys that need updating?
    • How will multi-database testing be implemented in CI?

Integration Approach

Stack Fit

  • Laravel Core:
    • Schema Builder: Native integration with Blueprint macros. No conflicts with core Laravel 10+.
    • Eloquent: Compatible with key resolution (e.g., getKey(), getIncrementing()), but may require custom model bindings for legacy assumptions.
    • Migrations: Supports incremental adoption—existing migrations remain unchanged until new tables are created.
  • Database Support:
    • PostgreSQL: Ideal for UUIDs, composite keys, and advanced indexing. Supports UUID type natively.
    • MySQL: Requires CHAR(36) for UUIDs or BINARY(16) for binary UUIDs. May need custom key generation logic.
    • SQLite: Limited support for non-integer PKs; may require workarounds (e.g., TEXT for UUIDs) or avoidance.
  • Tooling:
    • Laravel Forge/Vapor: Supports UUID/string PKs out of the box. No additional configuration needed.
    • Docker/Containerized DBs: Ensure DB images support the chosen key type (e.g., postgres:15-alpine for UUIDs, mysql:8.0 with CHAR(36)).
    • CI/CD: Tests must cover:
      • Key-type generation (e.g., UUIDs, ULIDs, integers).
      • Migration rollbacks and schema changes.
      • Polymorphic resolution across databases.
      • Foreign key constraints and cascading.
  • Dependencies:
    • UUID Generation: Uses ramsey/uuid or webmozart/assert under the hood. No additional dependencies required unless custom generation is needed.
    • Testing: Compatible with Pest/PHPUnit. May need custom assertions for key-type validation.

Migration Path

  1. Phase 1: Configuration (Pre-Migration)

    • Define config/database.php with primary_key_type (e.g., uuid, string, integer).
      'primary_key_type' => env('DB_PRIMARY_KEY_TYPE', 'uuid'),
      
    • Publish the config file if using a package:
      php artisan vendor:publish --tag="variable-keys-config"
      
    • Update .env with the desired key type:
      DB_PRIMARY_KEY_TYPE=uuid
      
  2. Phase 2: New Tables (Immediate Adoption)

    • Replace ->id() with ->variablePrimaryKey() in new migrations.
      Schema::create('users', function (Blueprint $table) {
          $table->variablePrimaryKey(PrimaryKeyType::UUID);
          $table->string('name');
          $table->timestamps();
      });
      
    • For polymorphic tables, use variableMorphs():
      Schema::create('comments', function (Blueprint $table) {
          $table->variablePrimaryKey(PrimaryKeyType::UUID);
          $table->variableMorphs(['commentable_id', 'commentable_type']);
          $table->text('body');
      });
      
  3. Phase 3: Foreign Keys (Consistent Relationships)

    • Use variableForeignKey() to ensure foreign keys match the primary key type:
      Schema::create('posts', function (Blueprint $table) {
          $table->variable
      
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui