Hi @pickab00
In preparing this reply, I've driven out the code explained below with TDD. I uploaded the code to this GitHub repo. If you want, you can clone it and adjust it to your specific needs. Tests are included ("Feature" Test, Unit Tests).
I don’t know if it is the best approach, but here is how I would do it:
You'll need these 3 models:
- MenuItem (for example "Fries”)
- Variant (representing variations on menu items, for example sizes)
- VariantOption (representing the options of a variation, for example: small, medium and large).
A "Menu Item" can have multiple "Variants" (like "size"). A "variant" in turn can have multiple options (like "large").
A "Variant" can be used in multiple "Menu Items", therefore a many-to-many relationship is appropriate. A "VariantOption" only belongs to a single "Variant" and a one-to-many relationship is appropriate.
// Menu Item model (MenuItem.php)
class MenuItem
{
public function variants()
{
return $this->belongsToMany(Variant::class);
}
}
// Variant model (Variant.php model)
class Variant
{
public function options()
{
return $this->hasMany(VariantOption::class);
}
}
// Variant Option (VariantOption.php model)
class VariantOption
{
public function variant()
{
$this->belongsTo(Variant::class)->with('options');
}
}
These models go with the following tables: (View the migrations)
-
menu_items table, columns: 'id', 'name', 'description'
-
variants table, columns: 'id', 'name'
-
variant_options table, columns: 'id', 'variant_id', 'option' (in which 'option' holds "large" for example)
-
menu_item_variant (pivot) table, columns: 'menu_item_id', 'variant_id'
The last table is a pivot table and facilitates the many-to-many relationship between "Menu Items" and "Variants".
Now, for example on how to interact with this system:
$menuItem = App\MenuItem::create(['name' => 'Fries', 'description' => 'Homemade fries']);
$variant = App\Variant::create(['name' => 'size']);
// Add sizes to the "size" variant
$small = new App\VariantOption(['variant_id' => $variant->id, 'option' => 'small']);
$medium = new App\VariantOption(['variant_id' => $variant->id, 'option' => 'medium']);
$large = new App\VariantOption(['variant_id' => $variant->id, 'option' => 'large']);
$variant->options()->saveMany([$small, $medium, $large]);
// Attach the variant to the MenuItem
$menuItem->variants()->attach($variant);