@sinres Any time you use a JSON column type in a relational database like MySQL or Postgres, there’s usually a Better Way™ to model your data.
For e-commerce sites where products have variations like this, I usually model a top-level product that has the common attributes (name, description, etc) and then that product will have many SKU models. This is how a physical store will also represent those products: a pair of shoes in size 9 will have a different SKU to the same pair of shoes but in size 9.5.
So, with that said, you can extract an “attribute” model. Your can then have a pivot table between SKUs and attributes where you record the value for that SKU and attribute combination:
public function up()
{
Schema::create('attribute_sku', function (Blueprint $table) {
$table->primary(['attribute_id', 'sku_id']);
$table->foreignId('attribute_id')->constrained()->cascadeOnDelete();
$table->foreignId('sku_id')->constrained()->cascadeOnDelete();
$table->string('value');
$table->unique(['attribute_id', 'sku_id', 'value']);
});
}
So you can create an attribute and set a value for it like this:
$sizeAttribute = Attribute::create([
'name' => 'Size',
]);
$sku = Sku::find($id); // Find SKU representing shoes in size 9.5
$sku->attributes()->syncWithoutDetaching($sizeAttribute, [
'value' => '9.5',
]);
