To implement the relationships for your meal planner, you can use a polymorphic many-to-many relationship. This allows a Meal to have multiple Ingredients and Dishes, and vice versa. Here's how you can set it up:
Database Migrations
You already have the meals and meal_components tables set up. You'll also need tables for ingredients and dishes.
// database/migrations/create_ingredients_table.php
Schema::create('ingredients', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
// database/migrations/create_dishes_table.php
Schema::create('dishes', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Models
Define the relationships in your models using the morphToMany and morphedByMany methods.
// app/Models/Meal.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Meal extends Model
{
public function components()
{
return $this->morphToMany(MealComponent::class, 'mealable', 'meal_components');
}
}
// app/Models/Ingredient.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Ingredient extends Model
{
public function meals()
{
return $this->morphedByMany(Meal::class, 'mealable', 'meal_components');
}
}
// app/Models/Dish.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Dish extends Model
{
public function meals()
{
return $this->morphedByMany(Meal::class, 'mealable', 'meal_components');
}
}
// app/Models/MealComponent.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class MealComponent extends Model
{
public function mealable()
{
return $this->morphTo();
}
}
Usage
To associate an Ingredient or Dish with a Meal, you can use the attach method:
$meal = Meal::find(1);
$ingredient = Ingredient::find(1);
$dish = Dish::find(1);
// Attach an ingredient
$meal->components()->attach($ingredient, ['quantity' => 2]);
// Attach a dish
$meal->components()->attach($dish, ['quantity' => 1]);
Explanation
- Polymorphic Many-to-Many: This setup allows a
Mealto have multipleIngredientsandDishesthrough a singlemeal_componentstable. - Morphs and MorphedByMany: These methods are used to define the polymorphic relationship.
morphToManyis used in theMealmodel to define the relationship withMealComponent, whilemorphedByManyis used inIngredientandDishmodels to define the inverse relationship.
This setup should give you the flexibility to manage meals composed of both ingredients and dishes efficiently.