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 Model Metadata Laravel Package

waad/laravel-model-metadata

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require waad/laravel-model-metadata
    php artisan vendor:publish --tag=metadata-config --tag=metadata-migrations
    php artisan migrate
    
  2. Apply Trait to Model: Use HasManyMetadata (for multiple metadata entries) or HasOneMetadata (for single metadata entry) on your Eloquent model:

    use Waad\Metadata\Traits\HasManyMetadata;
    
    class Post extends Model
    {
        use HasManyMetadata;
    }
    
  3. First Use Case: Attach metadata to a model instance:

    $post = Post::find(1);
    $post->metadata()->attach([
        'author_notes' => 'Draft needs review',
        'tags' => ['laravel', 'metadata']
    ]);
    

Where to Look First

  • Documentation: GitBook for advanced usage.
  • Config: config/model-metadata.php for customization (e.g., table name, caching).
  • Migrations: Check database/migrations/ for schema details.

Implementation Patterns

Common Workflows

  1. Attaching Metadata:

    // Single attachment (HasOneMetadata)
    $post->metadata()->attach(['key' => 'value']);
    
    // Multiple attachments (HasManyMetadata)
    $post->metadata()->attach([
        'key1' => 'value1',
        'key2' => ['nested', 'array']
    ]);
    
  2. Querying Metadata: Use whereMetadata() for JSON-based queries:

    // Exact match
    Post::whereMetadata('author_notes', 'Draft needs review')->get();
    
    // JSON array contains
    Post::whereMetadata('tags', 'like', '%laravel%')->get();
    
    // Nested JSON queries
    Post::whereMetadata('settings.theme', 'dark')->get();
    
  3. Caching: Enable caching in config/model-metadata.php and leverage cache()->remember() for performance:

    $metadata = Cache::remember("post.{$post->id}.metadata", now()->addHours(1), function () {
        return $post->metadata()->first();
    });
    
  4. Custom Relation Names: Override the default metadata() relation name:

    class Post extends Model
    {
        use HasManyMetadata;
    
        public function customMetadata()
        {
            return $this->metadata()->where('type', 'custom');
        }
    }
    
  5. Mass Assignment: Use fillMetadata() for bulk updates:

    $post->fillMetadata(['status' => 'published', 'views' => 100])->save();
    

Integration Tips

  • Events: Listen for metadata.attached or metadata.updated events via Event::listen().
  • Observers: Extend Waad\Metadata\Observers\MetadataObserver for custom logic.
  • APIs: Serialize metadata with $post->metadata->toArray() or use ->toJson() for JSON responses.

Gotchas and Tips

Pitfalls

  1. JSON Casting Conflicts:

    • If your model uses $casts = ['metadata' => 'array'], disable it to avoid conflicts with the package’s JSON handling.
    • Fix: Remove or override the cast in your model.
  2. Migration Issues:

    • If migrations fail, check config/model-metadata.php for correct table names and run php artisan migrate:fresh.
    • Tip: Use --pretend flag to debug migration SQL:
      php artisan migrate --pretend
      
  3. Caching Quirks:

    • Caching is disabled by default (MODEL_METADATA_CACHE_ENABLED). Enable it only in staging/production.
    • Warning: Clear cache after metadata updates:
      php artisan cache:clear
      
  4. Nested JSON Queries:

    • Use dot notation for nested keys (e.g., whereMetadata('user.settings.theme', 'dark')).
    • Gotcha: Deeply nested queries may slow performance. Index frequently queried paths.
  5. Trait Conflicts:

    • Avoid mixing HasManyMetadata and HasOneMetadata on the same model.
    • Solution: Use separate models or extend the traits.

Debugging

  • Log Metadata:
    \Log::info('Metadata:', ['data' => $post->metadata->toArray()]);
    
  • Check Raw SQL: Use Laravel’s query logging:
    \DB::enableQueryLog();
    Post::whereMetadata('key', 'value')->get();
    \Log::info(\DB::getQueryLog());
    

Extension Points

  1. Custom Metadata Model: Extend Waad\Metadata\Models\Metadata to add fields:

    class CustomMetadata extends Metadata
    {
        protected $casts = [
            'custom_field' => 'boolean',
        ];
    }
    

    Update config:

    'model' => App\Models\CustomMetadata::class,
    
  2. Custom Accessors: Add dynamic accessors to your model:

    public function getAuthorNotesAttribute()
    {
        return $this->metadata->get('author_notes');
    }
    
  3. Validation: Validate metadata before attachment:

    use Waad\Metadata\Rules\ValidMetadata;
    
    $request->validate([
        'metadata' => ['required', new ValidMetadata],
    ]);
    

Performance Tips

  • Indexing: Add indexes to metadata columns for frequently queried keys:
    Schema::table('model_metadata', function (Blueprint $table) {
        $table->index('key');
        $table->index('model_type');
        $table->index('model_id');
    });
    
  • Batch Operations: Use chunk() for large metadata updates:
    Post::chunk(100, function ($posts) {
        foreach ($posts as $post) {
            $post->metadata()->attach(['processed' => true]);
        }
    });
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope