====== Registro de comidas ======
Registro diario de las comidas.
===== Funcionalidades =====
* Registro de comidas
* Día
* Tipo (desayuno, comida, cena, picoteo)
* Asociación de comidas a categorías (Postres, Carnes, Pescados, Frutas...)
* Asociación de comidas a etiquetas
* Detalle de comida por ingredientes
===== Estructura de base de datos =====
==== Tipos de comida ====
* id
* nombre
* slug
* descripción
==== Comidas ====
* id
* usuario_id (opcional)
* nombre
* descripcion (opcional)
* fecha
* calorias
* tipo (desayuno, comida, cena, tentempié)
* id_categoria (opcional)
* lugar (casa, fuera)
==== Ingredientes ====
* id
* nombre
* id_categoria
* calorias_por_100g
==== Comida_Ingrediente ====
Tabla que relaciona comidas e ingredientes.
* id_comida
* id_ingrediente
* cantidad (gramos)
==== Categorías ====
* id
* nombre
* color?
==== Etiquetas ====
* id
* nombre
* slug
==== Comida_Etiqueta ====
Tabla que relaciona comidas y etiquetas
* id_comida
* id_tag
===== Herramientas empleadas =====
* Framework [[informatica:programacion:php:frameworks:laravel|Laravel]] (PHP)
===== Base de datos =====
Diagrama entidad-relación.
===== Tipos de comida =====
Según el momento del día:
* Desayuno
* Comida
* Cena
* Tentempié / picoteo / snack
==== Migración ====
php artisan make:migration create_meal_types_table
Contenido del fichero ''database/migrations/2025_03_30_164255_create_meal_types_table.php'':
id();
$table->string('name');
$table->string('slug')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('meal_types');
}
};
==== Modelo ====
Lo creamos con:
php artisan make:model MealType
Contenido del fichero generado ''app/Models/MealType.php'':
===== Categorías =====
Migración para la tabla de las **categorías**:
php artisan make:migration create_categories_table
Fichero con la migración (''database/migrations/2025_03_28_200000_create_categories_table.php''):
id();
$table->string('name')->unique();
$table->string('color')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('categories');
}
}
Modelo para las **categorías** (''app/Models/Category.php''):
hasMany(Meal::class);
}
public function ingredients()
{
return $this->hasMany(Ingredient::class);
}
}
==== Controlador ====
Creamos un controlador asociado al modelo de las categorías:
php artisan make:controller CategoryController -m Category
Se creará el fichero ''app/Http/Controllers/CategoryController.php'' con la firma de los 7 métodos:
* ''index()''
* ''create()''
* ''store()''
* ''show()''
* ''edit()''
* ''update()''
* ''destroy()''
==== Vistas ====
Creamos las vistas para todos los métodos del controlador menos ''store()'', ''update()'' y ''destroy()'':
php artisan make:view categories.index
php artisan make:view categories.create
php artisan make:view categories.show
php artisan make:view categories.edit
Se habrán creado los siguientes ficheros en el directorio ''resources/views/categories'':
* ''index.blade.php''
* ''create.blade.php''
* ''show.blade.php''
* ''edit.blade.php''
==== Rutas ====
En el fichero ''routes/web.php'' añadimos:
Route::resource('categories', CategoryController::class);
Podemos verificar con el siguiente comando las rutas registradas:
php artisan route:list
===== Comidas =====
==== Migración ====
**Migración** para la tabla de las **comidas**:
php artisan make:migration create_meals_table
Fichero con la migración (''database/migrations/2025_03_28_210000_create_meals_table.php''):
id();
$table->foreignId('user_id')->nullable()->constrained()->cascadeOnDelete();
$table->string('name');
$table->text('description')->nullable();
$table->dateTime('date_time');
$table->integer('calories')->nullable();
$table->enum('meal_type', ['desayuno', 'comida', 'cena', 'tentempié']);
$table->foreignId('category_id')->nullable()->constrained();
$table->enum('location_type', ['casa', 'fuera'])->default('casa');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('meals');
}
};
==== Modelo ====
Modelo para las categorías (''app/Models/Meal.php''):
'datetime',
];
// Relaciones
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
public function ingredients(): BelongsToMany
{
return $this->belongsToMany(Ingredient::class)
->withPivot('quantity')
->withTimestamps();
}
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class)
->withTimestamps();
}
// Accesor para el lugar
public function getLocationAttribute(): string
{
return match($this->location_type) {
'casa' => 'En casa',
'casa_familiar' => 'Casa de familiar',
'restaurante' => $this->restaurant ?? 'Restaurante',
default => 'Desconocido'
};
}
}
==== Controlador ====
Creamos un controlador asociado al modelo de las categorías:
php artisan make:controller MealController -m Meal
Se creará el fichero ''app/Http/Controllers/MealController.php'' con la firma de los 7 métodos:
* index()
* create()
* store()
* show()
* edit()
* update()
* destroy()
==== Vistas ====
Creamos las vistas para todos los métodos del controlador menos ''store()'', ''update()'' y ''destroy()'':
php artisan make:view meals.index
php artisan make:view meals.create
php artisan make:view meals.show
php artisan make:view meals.edit
Se habrán creado los siguientes ficheros en el directorio ''resources/views/meals'':
* ''index.blade.php''
* ''create.blade.php''
* ''show.blade.php''
* ''edit.blade.php''
==== Rutas ====
En el fichero ''routes/web.php'' añadimos:
Route::resource('meals', MealController::class);
Podemos verificar con el siguiente comando las rutas registradas:
php artisan route:list