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 Schemaless Attributes Laravel Package

spatie/laravel-schemaless-attributes

Add “schemaless” JSON attributes to Laravel Eloquent models. Store arbitrary key/value data in one JSON column with a fluent API: get/set via properties or arrays, dot-notation access, defaults, forget keys, and query scopes for matching attributes.

View on GitHub
Deep Wiki
Context7

Getting Started

Begin by installing the package via Composer:

composer require spatie/laravel-schemaless-attributes

Next, create a migration to add a JSON column to your model’s table using the schemalessAttributes macro:

Schema::table('products', function (Blueprint $table) {
    $table->schemalessAttributes('meta');
});

Then, in your Eloquent model, add the cast and a custom scope:

use Spatie\SchemalessAttributes\Casts\SchemalessAttributes;

class Product extends Model
{
    public $casts = [
        'meta' => SchemalessAttributes::class,
    ];

    public function scopeWithMeta(): Builder
    {
        return $this->meta->modelScope();
    }
}

You can now start using schemaless attributes immediately:

$product->meta->brand = 'Acme';
$product->save();

Implementation Patterns

  • Dynamic metadata: Store optional or evolving product features (e.g., weight, dimensions, certifications) without schema migrations.
  • User preferences: Save personalized settings (e.g., dark_mode, notifications) per user.
  • Configuration per tenant: In SaaS apps, store tenant-specific settings (e.g., branding, feature_flags) in a config JSON column.
  • Nested data access: Use dot notation for deeply nested values:
    $product->meta->set('specs.color', 'navy');
    $value = $product->meta->get('specs.color');
    
  • Bulk updates: Assign or update multiple attributes at once:
    $product->meta = ['color' => 'red', 'size' => 'L'];
    // or
    $product->meta->set(['color' => 'blue', 'stock' => 100]);
    
  • Querying by attributes: Use model scopes for filtering:
    Product::withMeta('color', 'red')->get();  
    Product::withMeta('specs.weight', '>', 5)->get();  
    Product::withMeta(['category' => 'tools', 'brand' => 'DeWalt'])->get();
    
  • Reusability across models: Extract common logic into a HasSchemalessAttributes trait to avoid repetition.

Gotchas and Tips

  • No automatic persistence: Modifying nested arrays directly (e.g., $product->meta['specs']['color'] = 'blue') won’t persist unless you assign the entire meta or call set(). Use dot notation ($product->meta->set('specs.color', 'blue')) or assign an array to trigger changes.
  • JSON casting pitfalls: Avoid storing non-JSON-serializable values (e.g., resources or closures). Since v2.5.2, this throws a JsonException.
  • Nested queries require -> operator: Use meta->color in scopes (not meta.color) when querying nested keys:
    Product::withMeta('specs->weight', '>', 5)->get();
    
  • unset() vs forget(): Use unset($product->meta['key']) (works via ArrayAccess) or $product->meta->forget('key')—but not both, as mixing may cause unexpected behavior. Always call save() after modifications.
  • Schemaless columns aren’t query-optimized by default: Add database-level indexes on commonly filtered keys for performance (e.g., MySQL: ALTER TABLE products ADD INDEX (meta->'$.color')), though this package doesn’t auto-generate them.
  • Multiple columns require SchemalessAttributesTrait: For models with >1 schemaless column (e.g., meta, settings), use the SchemalessAttributesTrait and declare them in $schemalessAttributes.
  • Debugging tip: Use $product->meta->all() or json_encode($product->meta) to inspect current values before saving.
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