diff --git a/app/Models/Ingredient.php b/app/Models/Ingredient.php index 3c61754..76714e3 100644 --- a/app/Models/Ingredient.php +++ b/app/Models/Ingredient.php @@ -7,12 +7,14 @@ use Illuminate\Database\Eloquent\Model; /** * @property int id - * @property string name - * @property string unit - * @property float calories - * @property float protein - * @property float fat - * @property float carbohydrates + * @property string name Ingredient base name. + * @property ?string detail Some additional detail about the ingredient (e.g. "small" with the name "onion"). + * @property float calories (per 100g). + * @property float protein (per 100g). + * @property float fat (per 100g). + * @property float carbohydrates (per 100g). + * @property ?float unit_weight Weight of one cup of the ingredient. + * @property ?float cup_weight Weight of one "unit" (e.g. an egg, onion, etc.) of the ingredient. */ class Ingredient extends Model { @@ -23,10 +25,24 @@ class Ingredient extends Model */ protected array $fillable = [ 'name', - 'unit', + 'detail', 'calories', 'protein', 'fat', 'carbohydrates', + 'unitWeight', + 'cupWeight', + ]; + + /** + * The attributes that should be cast. + */ + protected array $casts = [ + 'calories' => 'float', + 'protein' => 'float', + 'fat' => 'float', + 'carbohydrates' => 'float', + 'unit_weight' => 'float', + 'cup_weight' => 'float', ]; } diff --git a/app/Models/IngredientAmount.php b/app/Models/IngredientAmount.php index 5e40a7d..2d58993 100644 --- a/app/Models/IngredientAmount.php +++ b/app/Models/IngredientAmount.php @@ -8,9 +8,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; /** * @property int id - * @property float amount - * @property float unit - * @property int weight + * @property float amount Amount of ingredient. + * @property ?string unit Ingredient unit (tsp, tbsp, cup, or grams). + * @property int weight Weight of ingredient in full ingredient list (lowest first). * @property \App\Models\Ingredient ingredient * @property \App\Models\Recipe recipe */ @@ -27,6 +27,14 @@ class IngredientAmount extends Model 'weight', ]; + /** + * The attributes that should be cast. + */ + protected array $casts = [ + 'amount' => 'float', + 'weight' => 'int', + ]; + /** * @inheritdoc */ @@ -50,42 +58,39 @@ class IngredientAmount extends Model * Get total calories for the ingredient amount. */ public function calories(): float { - return $this->ingredient->calories * $this->amount * $this->unitMultiplier(); + return $this->ingredient->calories * $this->unitMultiplier(); } /** * Get total protein for the ingredient amount. */ public function protein(): float { - return $this->ingredient->protein * $this->amount * $this->unitMultiplier(); + return $this->ingredient->protein * $this->unitMultiplier(); } /** * Get total fat for the ingredient amount. */ public function fat(): float { - return $this->ingredient->fat * $this->amount * $this->unitMultiplier(); + return $this->ingredient->fat * $this->unitMultiplier(); } /** * Get total carbohydrates for the ingredient amount. */ public function carbohydrates(): float { - return $this->ingredient->carbohydrates * $this->amount * $this->unitMultiplier(); + return $this->ingredient->carbohydrates * $this->unitMultiplier(); } /** - * Get the multiplier for the ingredient unit and ingredient amount unit. + * Get the multiplier for the ingredient unit based on weight. */ private function unitMultiplier(): float { - return match (true) { - $this->ingredient->unit === 'tsp' && $this->unit === 'tbsp' => 3, - $this->ingredient->unit === 'tsp' && $this->unit === 'cup' => 48, - $this->ingredient->unit === 'tbsp' && $this->unit === 'tsp' => 1/3, - $this->ingredient->unit === 'tbsp' && $this->unit === 'cup' => 16, - $this->ingredient->unit === 'cup' && $this->unit === 'tsp' => 1/48, - $this->ingredient->unit === 'cup' && $this->unit === 'tbsp' => 1/16, + return match ($this->unit) { + null => $this->ingredient->unit_weight, + 'tsp' => 1/48, + 'tbsp' => 1/16, default => 1 - }; + } * $this->amount * ($this->ingredient->cup_weight ?? 1) / 100; } } diff --git a/app/Models/Recipe.php b/app/Models/Recipe.php index be355a6..a643d5e 100644 --- a/app/Models/Recipe.php +++ b/app/Models/Recipe.php @@ -26,6 +26,13 @@ class Recipe extends Model 'servings', ]; + /** + * The attributes that should be cast. + */ + protected array $casts = [ + 'servings' => 'int', + ]; + /** * @inheritdoc */ @@ -48,28 +55,28 @@ class Recipe extends Model /** * Get total recipe calories. */ - public function calories(): float { + public function caloriesTotal(): float { return $this->sumNutrient('calories'); } /** * Get total recipe protein. */ - public function protein(): float { + public function proteinTotal(): float { return $this->sumNutrient('protein'); } /** * Get total recipe fat. */ - public function fat(): float { + public function fatTotal(): float { return $this->sumNutrient('fat'); } /** * Get total recipe carbohydrates. */ - public function carbohydrates(): float { + public function carbohydratesTotal(): float { return $this->sumNutrient('carbohydrates'); } diff --git a/app/Models/RecipeStep.php b/app/Models/RecipeStep.php index c5ee4de..16be8bc 100644 --- a/app/Models/RecipeStep.php +++ b/app/Models/RecipeStep.php @@ -24,6 +24,13 @@ class RecipeStep extends Model 'step', ]; + /** + * The attributes that should be cast. + */ + protected array $casts = [ + 'number' => 'int', + ]; + /** * Get the Recipe this step belongs to. */ diff --git a/database/migrations/2020_12_21_214128_create_ingredients_table.php b/database/migrations/2020_12_21_214128_create_ingredients_table.php index b49a1f9..025ee8d 100644 --- a/database/migrations/2020_12_21_214128_create_ingredients_table.php +++ b/database/migrations/2020_12_21_214128_create_ingredients_table.php @@ -8,29 +8,27 @@ class CreateIngredientsTable extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { Schema::create('ingredients', function (Blueprint $table) { $table->id(); $table->string('name'); - $table->enum('unit', ['tsp', 'tbsp', 'cup'])->nullable(); + $table->string('detail')->nullable(); $table->unsignedFloat('calories')->default(0); $table->unsignedFloat('protein')->default(0); $table->unsignedFloat('fat')->default(0); $table->unsignedFloat('carbohydrates')->default(0); + $table->unsignedFloat('unit_weight')->nullable(); + $table->unsignedFloat('cup_weight')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::dropIfExists('ingredients'); } diff --git a/database/migrations/2020_12_21_215527_create_ingredient_amounts_table.php b/database/migrations/2020_12_21_215527_create_ingredient_amounts_table.php index dfe74d6..6826648 100644 --- a/database/migrations/2020_12_21_215527_create_ingredient_amounts_table.php +++ b/database/migrations/2020_12_21_215527_create_ingredient_amounts_table.php @@ -19,7 +19,7 @@ class CreateIngredientAmountsTable extends Migration $table->id(); $table->foreignIdFor(Ingredient::class); $table->unsignedFloat('amount'); - $table->enum('unit', ['tsp', 'tbsp', 'cup'])->nullable(); + $table->enum('unit', ['tsp', 'tbsp', 'cup', 'grams'])->nullable(); $table->foreignIdFor(Recipe::class); $table->unsignedInteger('weight'); $table->timestamps(); diff --git a/database/seeders/IngredientSeeder.php b/database/seeders/IngredientSeeder.php index 14be51c..e74d5a1 100644 --- a/database/seeders/IngredientSeeder.php +++ b/database/seeders/IngredientSeeder.php @@ -15,58 +15,64 @@ class IngredientSeeder extends Seeder $default_ingredients = [ [ 'name' => 'baking powder', - 'unit' => 'tsp', - 'calories' => 2.44, + 'calories' => 53, 'protein' => 0, 'fat' => 0, - 'carbohydrates' => 1.27 + 'carbohydrates' => 27.7, + 'cup_weight' => 220.8, ], [ 'name' => 'egg', - 'calories' => 71.5, - 'protein' => 6.28, - 'fat' => 4.76, - 'carbohydrates' => 0.36 + 'detail' => 'large', + 'calories' => 147, + 'protein' => 12.4, + 'fat' => 9.96, + 'carbohydrates' => 0.96, + 'unit_weight' => 50.3, ], [ - 'name' => 'flour, all-purpose', - 'unit' => 'cup', - 'calories' => 455, - 'protein' => 12.9, - 'fat' => 1.22, - 'carbohydrates' => 95.4 + 'name' => 'flour', + 'detail' => 'all-purpose', + 'calories' => 364, + 'protein' => 10.33, + 'fat' => 0.98, + 'carbohydrates' => 76.31, + 'cup_weight' => 125, ], [ - 'name' => 'milk, whole', - 'unit' => 'cup', - 'calories' => 146, - 'protein' => 8, - 'fat' => 7.81, - 'carbohydrates' => 11.4 + 'name' => 'milk', + 'detail' => 'whole', + 'calories' => 60, + 'protein' => 3.28, + 'fat' => 3.2, + 'carbohydrates' => 4.67, + 'cup_weight' => 244, ], [ 'name' => 'salt', - 'unit' => 'tsp', + 'detail' => 'table', 'calories' => 0, 'protein' => 0, 'fat' => 0, - 'carbohydrates' => 0 + 'carbohydrates' => 0, + 'cup_weight' => 292, ], [ - 'name' => 'sugar, white', - 'unit' => 'cup', - 'calories' => 770, + 'name' => 'sugar', + 'detail' => 'white', + 'calories' => 385, 'protein' => 0, - 'fat' => 0.54, - 'carbohydrates' => 199 + 'fat' => 0.32, + 'carbohydrates' => 99.6, + 'cup_weight' => 200, ], [ 'name' => 'vegetable oil', - 'unit' => 'tbsp', - 'calories' => 124, + 'calories' => 886, 'protein' => 0, - 'fat' => 14, - 'carbohydrates' => 199 + 'fat' => 100, + 'carbohydrates' => 0, + 'cup_weight' => 224, ], ]; Ingredient::factory()->createMany($default_ingredients); diff --git a/database/seeders/RecipeSeeder.php b/database/seeders/RecipeSeeder.php index 57e9884..a490807 100644 --- a/database/seeders/RecipeSeeder.php +++ b/database/seeders/RecipeSeeder.php @@ -25,7 +25,7 @@ class RecipeSeeder extends Seeder $weight = 0; $amounts = [ [ - 'ingredient_id' => Ingredient::where('name', 'flour, all-purpose') + 'ingredient_id' => Ingredient::where('name', 'flour') ->first()->id, 'amount' => 1, 'unit' => 'cup', @@ -33,7 +33,7 @@ class RecipeSeeder extends Seeder 'weight' => $weight++, ], [ - 'ingredient_id' => Ingredient::where('name', 'sugar, white') + 'ingredient_id' => Ingredient::where('name', 'sugar') ->first()->id, 'amount' => 2, 'unit' => 'tbsp', @@ -64,7 +64,7 @@ class RecipeSeeder extends Seeder 'weight' => $weight++, ], [ - 'ingredient_id' => Ingredient::where('name', 'milk, whole') + 'ingredient_id' => Ingredient::where('name', 'milk') ->first()->id, 'amount' => 1, 'unit' => 'cup',