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 Custom Fields Laravel Package

trappistes/laravel-custom-fields

Flexible EAV custom fields for Laravel Eloquent: add dynamic attributes without schema changes. Supports strong types (int, bool, json, date, ranges), polymorphic relations for any model, eager loading to avoid N+1, auto casting, batch upsert, validation, and soft deletes.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • EAV Pattern: The package implements an Entity-Attribute-Value (EAV) model, which is a natural fit for dynamic field requirements but introduces trade-offs in query performance and schema flexibility. This aligns well with use cases requiring ad-hoc field extensions (e.g., CMS plugins, user profiles, or configurable workflows).
  • Polymorphic Design: Supports custom fields across any Eloquent model via model_type/model_id, reducing schema bloat. However, this may complicate queries involving joins or aggregations.
  • Type Safety: Automatic type inference (e.g., json, datetime) and validation mitigate runtime errors but require careful handling of edge cases (e.g., malformed JSON or invalid dates).

Integration Feasibility

  • Laravel Compatibility: Officially supports Laravel 9–12 and PHP 8.1+, with minimal version constraints. The package leverages Eloquent traits and service providers, ensuring seamless integration into existing projects.
  • Database Agnostic: Works with any database supporting text/varchar fields and basic indexing. UUID/ULID support is optional but adds flexibility for distributed systems.
  • Migration Path: Zero-schema changes for basic use, but customizations (e.g., UUIDs, table renaming) require manual migration adjustments.

Technical Risk

  • Performance Overhead:
    • N+1 Queries: Without preloading (with('customFields')), dynamic field access triggers additional queries. Mitigated by the package’s preloading support but requires discipline in query construction.
    • EAV Complexity: Joins or aggregations on custom fields may require raw SQL or custom queries, increasing development effort.
  • Data Integrity:
    • No Schema Enforcement: Field names/types are validated at runtime, not at the database level. Risks include invalid data (e.g., malformed JSON) or reserved keyword collisions.
    • Soft Deletes: Custom fields are preserved on soft deletes, which may leak sensitive data if not managed carefully.
  • Testing Gaps:
    • Limited dependent packages (0) and minimal test coverage in the package itself suggest untested edge cases (e.g., concurrent writes, large-scale data volumes).
    • No explicit benchmarks for batch operations or high-write scenarios.

Key Questions

  1. Use Case Alignment:
    • Is the primary need for ad-hoc field extensibility (e.g., user profiles, CMS content) or structured data (where a traditional schema would suffice)?
    • Will custom fields be read-heavy (preloading mitigates N+1) or write-heavy (batch upsert helps but may still stress the database)?
  2. Data Volume:
    • How many custom fields per model are expected? EAV scales poorly with high cardinality (e.g., >100 fields/model).
    • What is the expected write frequency for custom fields? High-frequency updates may benefit from caching (e.g., Redis) or denormalization.
  3. Query Patterns:
    • Will queries frequently filter/join on custom fields? If so, raw SQL or materialized views may be needed.
    • Are there polymorphic relationships between models with custom fields? The package supports this, but complex queries may require custom logic.
  4. Maintenance:
    • Who will manage field naming conventions and type consistency? Lack of schema enforcement shifts validation to application logic.
    • How will deprecated fields be handled? The package lacks built-in field versioning or archiving.
  5. Alternatives:
    • Could JSON columns (PostgreSQL) or NoSQL (e.g., MongoDB) be a simpler fit for dynamic data?
    • Are there existing EAV solutions (e.g., spatie/laravel-activitylog for simpler use cases) that better match the scope?

Integration Approach

Stack Fit

  • Laravel Ecosystem: Ideal for projects already using Eloquent, Laravel’s query builder, and migrations. The package extends Eloquent models via traits (HasCustomFields), requiring minimal boilerplate.
  • Database Support: Works with MySQL, PostgreSQL, SQLite, and SQL Server. UUID/ULID support adds flexibility for non-integer primary keys.
  • Caching Layer: Can be paired with Laravel’s cache (e.g., Redis) to reduce database load for frequently accessed custom fields. Example:
    // Cache custom fields for 5 minutes
    $cachedFields = Cache::remember("user:{$user->id}:custom_fields", 300, function() use ($user) {
        return $user->getAllCustomFields();
    });
    
  • Testing: Uses Orchestra Testbench for integration tests. Projects should extend this for custom field-specific tests.

Migration Path

  1. Initial Setup:
    • Install via Composer: composer require trappistes/laravel-custom-fields.
    • Publish config: php artisan vendor:publish --provider="Trappistes\CustomFields\Providers\CustomFieldsServiceProvider".
    • Run migrations: php artisan migrate (creates custom_fields table).
  2. Model Integration:
    • Add use Trappistes\CustomFields\Traits\HasCustomFields; to target models.
    • Example:
      class User extends Model
      {
          use HasCustomFields;
      }
      
  3. Optional Customizations:
    • UUID/ULID Support: Modify the migration and create a custom CustomField model (as documented).
    • Field Validation: Extend the CustomField model to add business logic (e.g., field name whitelisting).
    • Preloading: Ensure queries use with('customFields') to avoid N+1:
      $users = User::with('customFields')->get();
      
  4. Data Migration:
    • For existing data, use setCustomFields() in a data seed or migration:
      User::find(1)->setCustomFields(['nickname' => 'John']);
      

Compatibility

  • Laravel Versions: Tested on 9–12. For Laravel 13+, verify compatibility due to potential breaking changes in Eloquent.
  • PHP Extensions: Requires json and pdo extensions (standard in Laravel).
  • Database Drivers: Supports all Laravel-supported databases, but performance may vary (e.g., PostgreSQL’s JSONB could be an alternative for nested data).
  • Third-Party Packages:
    • Soft Deletes: Works with Illuminate\Database\Eloquent\SoftDeletes.
    • API Resources: Custom fields can be included in API responses via App\Http\Resources\UserResource:
      public function toArray($request)
      {
          return [
              'name' => $this->name,
              'custom' => $this->getAllCustomFields(),
          ];
      }
      

Sequencing

  1. Phase 1: Core Integration
    • Add the package, publish config, and run migrations.
    • Integrate HasCustomFields into 1–2 pilot models (e.g., User, Product).
    • Test CRUD operations and preloading.
  2. Phase 2: Performance Optimization
    • Profile queries to identify N+1 issues; enforce preloading.
    • Implement caching for read-heavy fields.
    • Benchmark batch upsert for write-heavy workloads.
  3. Phase 3: Advanced Customization
    • Extend CustomField model for validation or UUID support.
    • Add field-specific logic (e.g., observers for critical fields).
  4. Phase 4: Monitoring
    • Track database growth in the custom_fields table.
    • Monitor query performance; optimize complex joins.

Operational Impact

Maintenance

  • Schema Management:
    • Pros: No migrations needed for new fields. Changes are code-driven (e.g., adding setCustomField('new_field', ...)).
    • Cons: Lack of schema documentation. Tools like Laravel Scout or custom scripts may be needed to track field usage.
  • Field Lifecycle:
    • Deprecation: No built-in mechanism. Requires application logic to ignore obsolete fields (e.g., check field names against a whitelist).
    • Archiving: Custom fields are not automatically archived on model deletion. Force delete removes them; soft delete preserves them.
  • Validation:
    • Runtime validation (e.g., field name format) reduces schema risks but shifts responsibility to the application layer. Consider adding:
      // Custom validation rule
      use Trappistes\CustomFields\Rules\ValidCustomFieldKey;
      
      $request->validate([
          'custom_field' => ['required', new ValidCustomFieldKey],
      ]);
      

Support

  • Debugging:
    • Field Access: Use hasCustomField() to check existence before access:
      if ($user->hasCustomField('age')) {
          $age = $user->getCustomField('age');
      }
      
    • Type Issues: Debug type inference by inspecting field_type in the custom_fields table.
    • Query Issues: Enable Laravel’s query logging to identify N+1 or inefficient joins.
  • Common Pitfalls:
    • Reserved Key Collisions: Avoid field names like `id
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.
symfony/ai-symfony-mate-extension
aashan/pimcore-mcp-bundle
solution-forest/ai-kit-core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php