Refactor "ingredients" as "foods"

This commit is contained in:
Christopher C. Wells 2020-12-30 15:06:22 -08:00
parent 7aab49a3cb
commit 2dd92c8d3a
33 changed files with 199 additions and 194 deletions

View File

@ -2,10 +2,10 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\IngredientAmount; use App\Models\FoodAmount;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class IngredientAmountController extends Controller class FoodAmountController extends Controller
{ {
/** /**
* Display a listing of the resource. * Display a listing of the resource.
@ -41,10 +41,10 @@ class IngredientAmountController extends Controller
/** /**
* Display the specified resource. * Display the specified resource.
* *
* @param \App\Models\IngredientAmount $ingredientAmount * @param \App\Models\FoodAmount $foodAmount
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function show(IngredientAmount $ingredientAmount) public function show(FoodAmount $foodAmount)
{ {
// //
} }
@ -52,10 +52,10 @@ class IngredientAmountController extends Controller
/** /**
* Show the form for editing the specified resource. * Show the form for editing the specified resource.
* *
* @param \App\Models\IngredientAmount $ingredientAmount * @param \App\Models\FoodAmount $foodAmount
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function edit(IngredientAmount $ingredientAmount) public function edit(FoodAmount $foodAmount)
{ {
// //
} }
@ -64,10 +64,10 @@ class IngredientAmountController extends Controller
* Update the specified resource in storage. * Update the specified resource in storage.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @param \App\Models\IngredientAmount $ingredientAmount * @param \App\Models\FoodAmount $foodAmount
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function update(Request $request, IngredientAmount $ingredientAmount) public function update(Request $request, FoodAmount $foodAmount)
{ {
// //
} }
@ -75,10 +75,10 @@ class IngredientAmountController extends Controller
/** /**
* Remove the specified resource from storage. * Remove the specified resource from storage.
* *
* @param \App\Models\IngredientAmount $ingredientAmount * @param \App\Models\FoodAmount $foodAmount
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function destroy(IngredientAmount $ingredientAmount) public function destroy(FoodAmount $foodAmount)
{ {
// //
} }

View File

@ -2,12 +2,12 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Ingredient; use App\Models\Food;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class IngredientController extends Controller class FoodController extends Controller
{ {
/** /**
* Display a listing of the resource. * Display a listing of the resource.
@ -16,8 +16,8 @@ class IngredientController extends Controller
*/ */
public function index(): View public function index(): View
{ {
return view('ingredients.index') return view('foods.index')
->with('ingredients', Ingredient::all()->sortBy('name')); ->with('foods', Food::all()->sortBy('name'));
} }
/** /**
@ -27,7 +27,7 @@ class IngredientController extends Controller
*/ */
public function create(): View public function create(): View
{ {
return view('ingredients.create'); return view('foods.create');
} }
/**newly /**newly
@ -47,18 +47,18 @@ class IngredientController extends Controller
'unit_weight' => 'required_without:cup_weight|nullable|numeric', 'unit_weight' => 'required_without:cup_weight|nullable|numeric',
'cup_weight' => 'required_without:unit_weight|nullable|numeric', 'cup_weight' => 'required_without:unit_weight|nullable|numeric',
]); ]);
/** @var \App\Models\Ingredient $ingredient */ /** @var \App\Models\Food $food */
$ingredient = tap(new Ingredient(array_filter($attributes)))->save(); $food = tap(new Food(array_filter($attributes)))->save();
return back()->with('message', "Ingredient {$ingredient->name} added!"); return back()->with('message', "Food {$food->name} added!");
} }
/** /**
* Display the specified resource. * Display the specified resource.
* *
* @param \App\Models\Ingredient $ingredient * @param \App\Models\Food $food
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function show(Ingredient $ingredient) public function show(Food $food)
{ {
// //
} }
@ -66,10 +66,10 @@ class IngredientController extends Controller
/** /**
* Show the form for editing the specified resource. * Show the form for editing the specified resource.
* *
* @param \App\Models\Ingredient $ingredient * @param \App\Models\Food $food
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function edit(Ingredient $ingredient) public function edit(Food $food)
{ {
// //
} }
@ -78,10 +78,10 @@ class IngredientController extends Controller
* Update the specified resource in storage. * Update the specified resource in storage.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @param \App\Models\Ingredient $ingredient * @param \App\Models\Food $food
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function update(Request $request, Ingredient $ingredient) public function update(Request $request, Food $food)
{ {
// //
} }
@ -89,10 +89,10 @@ class IngredientController extends Controller
/** /**
* Remove the specified resource from storage. * Remove the specified resource from storage.
* *
* @param \App\Models\Ingredient $ingredient * @param \App\Models\Food $food
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function destroy(Ingredient $ingredient) public function destroy(Food $food)
{ {
// //
} }

View File

@ -2,8 +2,8 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Ingredient; use App\Models\Food;
use App\Models\IngredientAmount; use App\Models\FoodAmount;
use App\Models\Recipe; use App\Models\Recipe;
use App\Models\RecipeStep; use App\Models\RecipeStep;
use App\Rules\ArrayNotEmpty; use App\Rules\ArrayNotEmpty;
@ -33,16 +33,16 @@ class RecipeController extends Controller
*/ */
public function create(): View public function create(): View
{ {
$ingredients = Ingredient::all(['id', 'name', 'detail'])->collect() $foods = Food::all(['id', 'name', 'detail'])->collect()
->map(function ($ingredient) { ->map(function ($food) {
return [ return [
'value' => $ingredient->id, 'value' => $food->id,
'label' => "{$ingredient->name}" . ($ingredient->detail ? ", {$ingredient->detail}" : ""), 'label' => "{$food->name}" . ($food->detail ? ", {$food->detail}" : ""),
]; ];
}); });
return view('recipes.create') return view('recipes.create')
->with('ingredients', $ingredients) ->with('foods', $foods)
->with('ingredient_units', new Collection([ ->with('food_units', new Collection([
['value' => 'tsp', 'label' => 'tsp.'], ['value' => 'tsp', 'label' => 'tsp.'],
['value' => 'tbsp', 'label' => 'tbsp.'], ['value' => 'tbsp', 'label' => 'tbsp.'],
['value' => 'cup', 'label' => 'cup'], ['value' => 'cup', 'label' => 'cup'],
@ -62,12 +62,12 @@ class RecipeController extends Controller
'name' => 'required|string', 'name' => 'required|string',
'description' => 'required|string', 'description' => 'required|string',
'servings' => 'required|numeric', 'servings' => 'required|numeric',
'ingredients_amount' => ['required', 'array', new ArrayNotEmpty], 'foods_amount' => ['required', 'array', new ArrayNotEmpty],
'ingredients_amount.*' => 'required_with:ingredients.*|nullable|numeric|min:0', 'foods_amount.*' => 'required_with:foods.*|nullable|numeric|min:0',
'ingredients_unit' => ['required', 'array', new ArrayNotEmpty], 'foods_unit' => ['required', 'array', new ArrayNotEmpty],
'ingredients_unit.*' => 'nullable|string', 'foods_unit.*' => 'nullable|string',
'ingredients' => ['required', 'array', new ArrayNotEmpty], 'foods' => ['required', 'array', new ArrayNotEmpty],
'ingredients.*' => 'required_with:ingredients_amount.*|nullable|exists:App\Models\Ingredient,id', 'foods.*' => 'required_with:foods_amount.*|nullable|exists:App\Models\Food,id',
'steps' => ['required', 'array', new ArrayNotEmpty], 'steps' => ['required', 'array', new ArrayNotEmpty],
'steps.*' => 'nullable|string', 'steps.*' => 'nullable|string',
]); ]);
@ -84,17 +84,17 @@ class RecipeController extends Controller
return; return;
} }
$ingredient_amounts = []; $food_amounts = [];
$weight = 0; $weight = 0;
foreach (array_filter($input['ingredients_amount']) as $key => $amount) { foreach (array_filter($input['foods_amount']) as $key => $amount) {
$ingredient_amounts[$key] = new IngredientAmount([ $food_amounts[$key] = new FoodAmount([
'amount' => (float) $amount, 'amount' => (float) $amount,
'unit' => $input['ingredients_unit'][$key], 'unit' => $input['foods_unit'][$key],
'weight' => $weight++, 'weight' => $weight++,
]); ]);
$ingredient_amounts[$key]->ingredient()->associate($input['ingredients'][$key]); $food_amounts[$key]->food()->associate($input['foods'][$key]);
} }
$recipe->ingredientAmounts()->saveMany($ingredient_amounts); $recipe->foodAmounts()->saveMany($food_amounts);
$steps = []; $steps = [];
$number = 1; $number = 1;
@ -104,7 +104,7 @@ class RecipeController extends Controller
'step' => $step, 'step' => $step,
]); ]);
} }
$recipe->ingredientAmounts()->saveMany($steps); $recipe->foodAmounts()->saveMany($steps);
}); });
} catch (\Exception $e) { } catch (\Exception $e) {
DB::rollBack(); DB::rollBack();

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\JsonApi\IngredientAmounts; namespace App\JsonApi\FoodAmounts;
use CloudCreativity\LaravelJsonApi\Eloquent\AbstractAdapter; use CloudCreativity\LaravelJsonApi\Eloquent\AbstractAdapter;
use CloudCreativity\LaravelJsonApi\Eloquent\BelongsTo; use CloudCreativity\LaravelJsonApi\Eloquent\BelongsTo;
@ -32,7 +32,7 @@ class Adapter extends AbstractAdapter
*/ */
public function __construct(StandardStrategy $paging) public function __construct(StandardStrategy $paging)
{ {
parent::__construct(new \App\Models\IngredientAmount(), $paging); parent::__construct(new \App\Models\FoodAmount(), $paging);
} }
/** /**
@ -45,7 +45,7 @@ class Adapter extends AbstractAdapter
$this->filterWithScopes($query, $filters); $this->filterWithScopes($query, $filters);
} }
protected function ingredient(): BelongsTo protected function food(): BelongsTo
{ {
return $this->belongsTo(); return $this->belongsTo();
} }

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\JsonApi\IngredientAmounts; namespace App\JsonApi\FoodAmounts;
use Neomerx\JsonApi\Schema\SchemaProvider; use Neomerx\JsonApi\Schema\SchemaProvider;
@ -10,7 +10,7 @@ class Schema extends SchemaProvider
/** /**
* @var string * @var string
*/ */
protected $resourceType = 'ingredient-amounts'; protected $resourceType = 'food-amounts';
/** /**
* @inheritdoc * @inheritdoc
@ -21,7 +21,7 @@ class Schema extends SchemaProvider
} }
/** /**
* @param \App\Models\IngredientAmount $resource * @param \App\Models\FoodAmount $resource
* *
* @return array * @return array
*/ */
@ -48,12 +48,12 @@ class Schema extends SchemaProvider
public function getRelationships($resource, $isPrimary, array $includeRelationships): array public function getRelationships($resource, $isPrimary, array $includeRelationships): array
{ {
return [ return [
'ingredient' => [ 'food' => [
self::SHOW_SELF => true, self::SHOW_SELF => true,
self::SHOW_RELATED => true, self::SHOW_RELATED => true,
self::SHOW_DATA => isset($includeRelationships['ingredient']), self::SHOW_DATA => isset($includeRelationships['food']),
self::DATA => function () use ($resource) { self::DATA => function () use ($resource) {
return $resource->ingredient; return $resource->food;
}, },
], ],
'recipe' => [ 'recipe' => [

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\JsonApi\Ingredients; namespace App\JsonApi\Foods;
use CloudCreativity\LaravelJsonApi\Eloquent\AbstractAdapter; use CloudCreativity\LaravelJsonApi\Eloquent\AbstractAdapter;
use CloudCreativity\LaravelJsonApi\Pagination\StandardStrategy; use CloudCreativity\LaravelJsonApi\Pagination\StandardStrategy;
@ -31,7 +31,7 @@ class Adapter extends AbstractAdapter
*/ */
public function __construct(StandardStrategy $paging) public function __construct(StandardStrategy $paging)
{ {
parent::__construct(new \App\Models\Ingredient(), $paging); parent::__construct(new \App\Models\Food(), $paging);
} }
/** /**

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\JsonApi\Ingredients; namespace App\JsonApi\Foods;
use Neomerx\JsonApi\Schema\SchemaProvider; use Neomerx\JsonApi\Schema\SchemaProvider;
@ -10,7 +10,7 @@ class Schema extends SchemaProvider
/** /**
* @var string * @var string
*/ */
protected $resourceType = 'ingredients'; protected $resourceType = 'foods';
/** /**
* @inheritdoc * @inheritdoc
@ -21,7 +21,7 @@ class Schema extends SchemaProvider
} }
/** /**
* @param \App\Models\Ingredient $resource * @param \App\Models\Food $resource
* *
* @return array * @return array
*/ */

View File

@ -45,7 +45,7 @@ class Adapter extends AbstractAdapter
$this->filterWithScopes($query, $filters); $this->filterWithScopes($query, $filters);
} }
protected function ingredientAmounts(): HasMany protected function foodAmounts(): HasMany
{ {
return $this->hasMany(); return $this->hasMany();
} }

View File

@ -62,12 +62,12 @@ class Schema extends SchemaProvider
return $resource->steps; return $resource->steps;
}, },
], ],
'ingredient-amounts' => [ 'food-amounts' => [
self::SHOW_SELF => true, self::SHOW_SELF => true,
self::SHOW_RELATED => true, self::SHOW_RELATED => true,
self::SHOW_DATA => isset($includeRelationships['ingredient-amounts']), self::SHOW_DATA => isset($includeRelationships['food-amounts']),
self::DATA => function () use ($resource) { self::DATA => function () use ($resource) {
return $resource->ingredientAmounts; return $resource->foodAmounts;
}, },
] ]
]; ];

View File

@ -7,23 +7,28 @@ use Illuminate\Database\Eloquent\Model;
/** /**
* @property int id * @property int id
* @property string name Ingredient base name. * @property string name Food base name.
* @property ?string detail Some additional detail about the ingredient (e.g. "small" with the name "onion"). * @property ?string detail Some additional detail about the food (e.g. "small" with the name "onion").
* @property float carbohydrates (per 100g). * @property float carbohydrates (per 100g).
* @property float calories (per 100g). * @property float calories (per 100g).
* @property float cholesterol (per 100g). * @property float cholesterol (per 100g).
* @property float fat (per 100g). * @property float fat (per 100g).
* @property float protein (per 100g). * @property float protein (per 100g).
* @property float sodium (per 100g). * @property float sodium (per 100g).
* @property ?float unit_weight Weight of one cup of the ingredient. * @property ?float unit_weight Weight of one cup of the food.
* @property ?float cup_weight Weight of one "unit" (e.g. an egg, onion, etc.) of the ingredient. * @property ?float cup_weight Weight of one "unit" (e.g. an egg, onion, etc.) of the food.
* @property \Illuminate\Support\Carbon created_at * @property \Illuminate\Support\Carbon created_at
* @property \Illuminate\Support\Carbon updated_at * @property \Illuminate\Support\Carbon updated_at
*/ */
class Ingredient extends Model class Food extends Model
{ {
use HasFactory; use HasFactory;
/**
* @inheritdoc
*/
protected $table = 'foods';
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -8,10 +8,10 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
/** /**
* @property int id * @property int id
* @property float amount Amount of ingredient. * @property float amount Amount of food.
* @property ?string unit Ingredient unit (tsp, tbsp, cup, or grams). * @property ?string unit Food unit (tsp, tbsp, cup, or grams).
* @property int weight Weight of ingredient in full ingredient list (lowest first). * @property int weight Weight of food in full food list (lowest first).
* @property \App\Models\Ingredient ingredient * @property \App\Models\Food food
* @property \App\Models\Recipe recipe * @property \App\Models\Recipe recipe
* @property \Illuminate\Support\Carbon created_at * @property \Illuminate\Support\Carbon created_at
* @property \Illuminate\Support\Carbon updated_at * @property \Illuminate\Support\Carbon updated_at
@ -22,7 +22,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
* @method float protein Get total protein. * @method float protein Get total protein.
* @method float sodium Get total sodium. * @method float sodium Get total sodium.
*/ */
class IngredientAmount extends Model class FoodAmount extends Model
{ {
use HasFactory; use HasFactory;
@ -46,7 +46,7 @@ class IngredientAmount extends Model
/** /**
* @inheritdoc * @inheritdoc
*/ */
protected $with = ['ingredient']; protected $with = ['food'];
/** /**
* Nutrient calculation methods. * Nutrient calculation methods.
@ -61,10 +61,10 @@ class IngredientAmount extends Model
]; ];
/** /**
* Get the Ingredient this amount belongs to. * Get the Food this amount belongs to.
*/ */
public function ingredient(): BelongsTo { public function food(): BelongsTo {
return $this->belongsTo(Ingredient::class); return $this->belongsTo(Food::class);
} }
/** /**
@ -86,7 +86,7 @@ class IngredientAmount extends Model
*/ */
public function __call($method, $parameters): mixed { public function __call($method, $parameters): mixed {
if (in_array($method, $this->nutrientMethods)) { if (in_array($method, $this->nutrientMethods)) {
return $this->ingredient->{$method} * $this->unitMultiplier(); return $this->food->{$method} * $this->unitMultiplier();
} }
else { else {
return parent::__call($method, $parameters); return parent::__call($method, $parameters);
@ -94,19 +94,19 @@ class IngredientAmount extends Model
} }
/** /**
* Get the multiplier for the ingredient unit based on weight. * Get the multiplier for the food unit based on weight.
* *
* Unit weight will be specified for ingredients that are added by unit * Unit weight will be specified for foods that are added by unit
* (e.g. eggs, vegetables, etc.) and cup weight (the weight of the * (e.g. eggs, vegetables, etc.) and cup weight (the weight of the
* ingredient equal to one cup) will be specified for ingredients that are * food equal to one cup) will be specified for foods that are
* measured (e.g. flour, milk, etc.). * measured (e.g. flour, milk, etc.).
*/ */
private function unitMultiplier(): float { private function unitMultiplier(): float {
return match ($this->unit) { return match ($this->unit) {
null => $this->ingredient->unit_weight, null => $this->food->unit_weight,
'tsp' => 1/48, 'tsp' => 1/48,
'tbsp' => 1/16, 'tbsp' => 1/16,
default => 1 default => 1
} * $this->amount * ($this->ingredient->cup_weight ?? 1) / 100; } * $this->amount * ($this->food->cup_weight ?? 1) / 100;
} }
} }

View File

@ -12,7 +12,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
* @property string description * @property string description
* @property int servings * @property int servings
* @property \App\Models\RecipeStep[] steps * @property \App\Models\RecipeStep[] steps
* @property \App\Models\IngredientAmount[] ingredientAmounts * @property \App\Models\FoodAmount[] foodAmounts
* @property \Illuminate\Support\Carbon created_at * @property \Illuminate\Support\Carbon created_at
* @property \Illuminate\Support\Carbon updated_at * @property \Illuminate\Support\Carbon updated_at
* @method float caloriesTotal Get total calories. * @method float caloriesTotal Get total calories.
@ -51,7 +51,7 @@ class Recipe extends Model
/** /**
* @inheritdoc * @inheritdoc
*/ */
protected $with = ['steps', 'ingredientAmounts']; protected $with = ['steps', 'foodAmounts'];
/** /**
* Nutrient total calculation methods. * Nutrient total calculation methods.
@ -85,10 +85,10 @@ class Recipe extends Model
} }
/** /**
* Get the Ingredient Amounts used for this Recipe. * Get the Food Amounts used for this Recipe.
*/ */
public function ingredientAmounts(): HasMany { public function foodAmounts(): HasMany {
return $this->hasMany(IngredientAmount::class)->orderBy('weight'); return $this->hasMany(FoodAmount::class)->orderBy('weight');
} }
/** /**
@ -123,7 +123,7 @@ class Recipe extends Model
} }
/** /**
* Sum a specific nutrient for all ingredient amounts. * Sum a specific nutrient for all food amounts.
* *
* @param string $nutrient * @param string $nutrient
* Nutrient to sum. * Nutrient to sum.
@ -132,8 +132,8 @@ class Recipe extends Model
*/ */
private function sumNutrient(string $nutrient): float { private function sumNutrient(string $nutrient): float {
$sum = 0; $sum = 0;
foreach ($this->ingredientAmounts as $ingredientAmount) { foreach ($this->foodAmounts as $foodAmount) {
$sum += $ingredientAmount->{$nutrient}(); $sum += $foodAmount->{$nutrient}();
} }
return $sum; return $sum;
} }

View File

@ -66,8 +66,8 @@ return [
| `'posts' => App\Post::class` | `'posts' => App\Post::class`
*/ */
'resources' => [ 'resources' => [
'ingredients' => \App\Models\Ingredient::class, 'foods' => \App\Models\Food::class,
'ingredient-amounts' => \App\Models\IngredientAmount::class, 'food-amounts' => \App\Models\FoodAmount::class,
'recipes' => \App\Models\Recipe::class, 'recipes' => \App\Models\Recipe::class,
'recipe-steps' => \App\Models\RecipeStep::class, 'recipe-steps' => \App\Models\RecipeStep::class,
], ],

View File

@ -2,17 +2,17 @@
namespace Database\Factories; namespace Database\Factories;
use App\Models\Ingredient; use App\Models\FoodAmount;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
class IngredientFactory extends Factory class FoodAmountFactory extends Factory
{ {
/** /**
* The name of the factory's corresponding model. * The name of the factory's corresponding model.
* *
* @var string * @var string
*/ */
protected $model = Ingredient::class; protected $model = FoodAmount::class;
/** /**
* Define the model's default state. * Define the model's default state.

View File

@ -2,17 +2,17 @@
namespace Database\Factories; namespace Database\Factories;
use App\Models\IngredientAmount; use App\Models\Food;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
class IngredientAmountFactory extends Factory class FoodFactory extends Factory
{ {
/** /**
* The name of the factory's corresponding model. * The name of the factory's corresponding model.
* *
* @var string * @var string
*/ */
protected $model = IngredientAmount::class; protected $model = Food::class;
/** /**
* Define the model's default state. * Define the model's default state.

View File

@ -4,14 +4,14 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
class CreateIngredientsTable extends Migration class CreateFoodsTable extends Migration
{ {
/** /**
* Run the migrations. * Run the migrations.
*/ */
public function up(): void public function up(): void
{ {
Schema::create('ingredients', function (Blueprint $table) { Schema::create('foods', function (Blueprint $table) {
$table->id(); $table->id();
$table->string('name'); $table->string('name');
$table->string('detail')->nullable(); $table->string('detail')->nullable();
@ -32,6 +32,6 @@ class CreateIngredientsTable extends Migration
*/ */
public function down(): void public function down(): void
{ {
Schema::dropIfExists('ingredients'); Schema::dropIfExists('foods');
} }
} }

View File

@ -1,12 +1,12 @@
<?php <?php
use App\Models\Ingredient; use App\Models\Food;
use App\Models\Recipe; use App\Models\Recipe;
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
class CreateIngredientAmountsTable extends Migration class CreateFoodAmountsTable extends Migration
{ {
/** /**
* Run the migrations. * Run the migrations.
@ -15,9 +15,9 @@ class CreateIngredientAmountsTable extends Migration
*/ */
public function up() public function up()
{ {
Schema::create('ingredient_amounts', function (Blueprint $table) { Schema::create('food_amounts', function (Blueprint $table) {
$table->id(); $table->id();
$table->foreignIdFor(Ingredient::class); $table->foreignIdFor(Food::class);
$table->unsignedFloat('amount'); $table->unsignedFloat('amount');
$table->enum('unit', ['tsp', 'tbsp', 'cup', 'grams'])->nullable(); $table->enum('unit', ['tsp', 'tbsp', 'cup', 'grams'])->nullable();
$table->foreignIdFor(Recipe::class); $table->foreignIdFor(Recipe::class);
@ -33,6 +33,6 @@ class CreateIngredientAmountsTable extends Migration
*/ */
public function down() public function down()
{ {
Schema::dropIfExists('ingredient_amounts'); Schema::dropIfExists('food_amounts');
} }
} }

View File

@ -11,7 +11,7 @@ class DatabaseSeeder extends Seeder
*/ */
public function run(): void public function run(): void
{ {
$this->call(IngredientSeeder::class); $this->call(FoodSeeder::class);
$this->call(RecipeSeeder::class); $this->call(RecipeSeeder::class);
} }
} }

View File

@ -2,17 +2,17 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Models\Ingredient; use App\Models\Food;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
class IngredientSeeder extends Seeder class FoodSeeder extends Seeder
{ {
/** /**
* Run the database seeds. * Run the database seeds.
*/ */
public function run(): void public function run(): void
{ {
$default_ingredients = [ $default_foods = [
[ [
'name' => 'baking powder', 'name' => 'baking powder',
'calories' => 53, 'calories' => 53,
@ -75,6 +75,6 @@ class IngredientSeeder extends Seeder
'cup_weight' => 224, 'cup_weight' => 224,
], ],
]; ];
Ingredient::factory()->createMany($default_ingredients); Food::factory()->createMany($default_foods);
} }
} }

View File

@ -2,8 +2,8 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Models\Ingredient; use App\Models\Food;
use App\Models\IngredientAmount; use App\Models\FoodAmount;
use App\Models\Recipe; use App\Models\Recipe;
use App\Models\RecipeStep; use App\Models\RecipeStep;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
@ -25,7 +25,7 @@ class RecipeSeeder extends Seeder
$weight = 0; $weight = 0;
$amounts = [ $amounts = [
[ [
'ingredient_id' => Ingredient::where('name', 'flour') 'food_id' => Food::where('name', 'flour')
->first()->id, ->first()->id,
'amount' => 1, 'amount' => 1,
'unit' => 'cup', 'unit' => 'cup',
@ -33,7 +33,7 @@ class RecipeSeeder extends Seeder
'weight' => $weight++, 'weight' => $weight++,
], ],
[ [
'ingredient_id' => Ingredient::where('name', 'sugar') 'food_id' => Food::where('name', 'sugar')
->first()->id, ->first()->id,
'amount' => 2, 'amount' => 2,
'unit' => 'tbsp', 'unit' => 'tbsp',
@ -41,7 +41,7 @@ class RecipeSeeder extends Seeder
'weight' => $weight++, 'weight' => $weight++,
], ],
[ [
'ingredient_id' => Ingredient::where('name', 'baking powder') 'food_id' => Food::where('name', 'baking powder')
->first()->id, ->first()->id,
'amount' => 2, 'amount' => 2,
'unit' => 'tsp', 'unit' => 'tsp',
@ -49,7 +49,7 @@ class RecipeSeeder extends Seeder
'weight' => $weight++, 'weight' => $weight++,
], ],
[ [
'ingredient_id' => Ingredient::where('name', 'salt') 'food_id' => Food::where('name', 'salt')
->first()->id, ->first()->id,
'amount' => 1, 'amount' => 1,
'unit' => 'tsp', 'unit' => 'tsp',
@ -57,14 +57,14 @@ class RecipeSeeder extends Seeder
'weight' => $weight++, 'weight' => $weight++,
], ],
[ [
'ingredient_id' => Ingredient::where('name', 'egg') 'food_id' => Food::where('name', 'egg')
->first()->id, ->first()->id,
'amount' => 1, 'amount' => 1,
'recipe_id' => $recipe->id, 'recipe_id' => $recipe->id,
'weight' => $weight++, 'weight' => $weight++,
], ],
[ [
'ingredient_id' => Ingredient::where('name', 'milk') 'food_id' => Food::where('name', 'milk')
->first()->id, ->first()->id,
'amount' => 1, 'amount' => 1,
'unit' => 'cup', 'unit' => 'cup',
@ -72,7 +72,7 @@ class RecipeSeeder extends Seeder
'weight' => $weight++, 'weight' => $weight++,
], ],
[ [
'ingredient_id' => Ingredient::where('name', 'vegetable oil') 'food_id' => Food::where('name', 'vegetable oil')
->first()->id, ->first()->id,
'amount' => 2, 'amount' => 2,
'unit' => 'tbsp', 'unit' => 'tbsp',
@ -80,7 +80,7 @@ class RecipeSeeder extends Seeder
'weight' => $weight++, 'weight' => $weight++,
], ],
]; ];
IngredientAmount::factory()->createMany($amounts); FoodAmount::factory()->createMany($amounts);
$steps = [ $steps = [
[ [

View File

@ -18,18 +18,18 @@
<!-- Password --> <!-- Password -->
<div> <div>
<x-label for="password" :value="__('Password')" /> <x-inputs.label for="password" :value="__('Password')" />
<x-input id="password" class="block mt-1 w-full" <x-inputs.input id="password" class="block mt-1 w-full"
type="password" type="password"
name="password" name="password"
required autocomplete="current-password" /> required autocomplete="current-password" />
</div> </div>
<div class="flex justify-end mt-4"> <div class="flex justify-end mt-4">
<x-button> <x-inputs.button>
{{ __('Confirm') }} {{ __('Confirm') }}
</x-button> </x-inputs.button>
</div> </div>
</form> </form>
</x-auth-card> </x-auth-card>

View File

@ -21,15 +21,15 @@
<!-- Email Address --> <!-- Email Address -->
<div> <div>
<x-label for="email" :value="__('Email')" /> <x-inputs.label for="email" :value="__('Email')" />
<x-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus /> <x-inputs.input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus />
</div> </div>
<div class="flex items-center justify-end mt-4"> <div class="flex items-center justify-end mt-4">
<x-button> <x-inputs.button>
{{ __('Email Password Reset Link') }} {{ __('Email Password Reset Link') }}
</x-button> </x-inputs.button>
</div> </div>
</form> </form>
</x-auth-card> </x-auth-card>

View File

@ -17,16 +17,16 @@
<!-- Email Address --> <!-- Email Address -->
<div> <div>
<x-label for="email" :value="__('Email')" /> <x-inputs.label for="email" :value="__('Email')" />
<x-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus /> <x-inputs.input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus />
</div> </div>
<!-- Password --> <!-- Password -->
<div class="mt-4"> <div class="mt-4">
<x-label for="password" :value="__('Password')" /> <x-inputs.label for="password" :value="__('Password')" />
<x-input id="password" class="block mt-1 w-full" <x-inputs.input id="password" class="block mt-1 w-full"
type="password" type="password"
name="password" name="password"
required autocomplete="current-password" /> required autocomplete="current-password" />
@ -47,9 +47,9 @@
</a> </a>
@endif @endif
<x-button class="ml-3"> <x-inputs.button class="ml-3">
{{ __('Login') }} {{ __('Login') }}
</x-button> </x-inputs.button>
</div> </div>
</form> </form>
</x-auth-card> </x-auth-card>

View File

@ -14,23 +14,23 @@
<!-- Name --> <!-- Name -->
<div> <div>
<x-label for="name" :value="__('Name')" /> <x-inputs.label for="name" :value="__('Name')" />
<x-input id="name" class="block mt-1 w-full" type="text" name="name" :value="old('name')" required autofocus /> <x-inputs.input id="name" class="block mt-1 w-full" type="text" name="name" :value="old('name')" required autofocus />
</div> </div>
<!-- Email Address --> <!-- Email Address -->
<div class="mt-4"> <div class="mt-4">
<x-label for="email" :value="__('Email')" /> <x-inputs.label for="email" :value="__('Email')" />
<x-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required /> <x-inputs.input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required />
</div> </div>
<!-- Password --> <!-- Password -->
<div class="mt-4"> <div class="mt-4">
<x-label for="password" :value="__('Password')" /> <x-inputs.label for="password" :value="__('Password')" />
<x-input id="password" class="block mt-1 w-full" <x-inputs.input id="password" class="block mt-1 w-full"
type="password" type="password"
name="password" name="password"
required autocomplete="new-password" /> required autocomplete="new-password" />
@ -38,9 +38,9 @@
<!-- Confirm Password --> <!-- Confirm Password -->
<div class="mt-4"> <div class="mt-4">
<x-label for="password_confirmation" :value="__('Confirm Password')" /> <x-inputs.label for="password_confirmation" :value="__('Confirm Password')" />
<x-input id="password_confirmation" class="block mt-1 w-full" <x-inputs.input id="password_confirmation" class="block mt-1 w-full"
type="password" type="password"
name="password_confirmation" required /> name="password_confirmation" required />
</div> </div>
@ -50,9 +50,9 @@
{{ __('Already registered?') }} {{ __('Already registered?') }}
</a> </a>
<x-button class="ml-4"> <x-inputs.button class="ml-4">
{{ __('Register') }} {{ __('Register') }}
</x-button> </x-inputs.button>
</div> </div>
</form> </form>
</x-auth-card> </x-auth-card>

View File

@ -17,31 +17,31 @@
<!-- Email Address --> <!-- Email Address -->
<div> <div>
<x-label for="email" :value="__('Email')" /> <x-inputs.label for="email" :value="__('Email')" />
<x-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email', $request->email)" required autofocus /> <x-inputs.input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email', $request->email)" required autofocus />
</div> </div>
<!-- Password --> <!-- Password -->
<div class="mt-4"> <div class="mt-4">
<x-label for="password" :value="__('Password')" /> <x-inputs.label for="password" :value="__('Password')" />
<x-input id="password" class="block mt-1 w-full" type="password" name="password" required /> <x-inputs.input id="password" class="block mt-1 w-full" type="password" name="password" required />
</div> </div>
<!-- Confirm Password --> <!-- Confirm Password -->
<div class="mt-4"> <div class="mt-4">
<x-label for="password_confirmation" :value="__('Confirm Password')" /> <x-inputs.label for="password_confirmation" :value="__('Confirm Password')" />
<x-input id="password_confirmation" class="block mt-1 w-full" <x-inputs.input id="password_confirmation" class="block mt-1 w-full"
type="password" type="password"
name="password_confirmation" required /> name="password_confirmation" required />
</div> </div>
<div class="flex items-center justify-end mt-4"> <div class="flex items-center justify-end mt-4">
<x-button> <x-inputs.button>
{{ __('Reset Password') }} {{ __('Reset Password') }}
</x-button> </x-inputs.button>
</div> </div>
</form> </form>
</x-auth-card> </x-auth-card>

View File

@ -21,9 +21,9 @@
@csrf @csrf
<div> <div>
<x-button> <x-inputs.button>
{{ __('Resend Verification Email') }} {{ __('Resend Verification Email') }}
</x-button> </x-inputs.button>
</div> </div>
</form> </form>

View File

@ -1,7 +1,7 @@
<x-app-layout> <x-app-layout>
<x-slot name="header"> <x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight"> <h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Add Ingredient') }} {{ __('Add Food') }}
</h2> </h2>
</x-slot> </x-slot>
@ -25,7 +25,7 @@
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200"> <div class="p-6 bg-white border-b border-gray-200">
<form method="POST" action="{{ route('ingredients.store') }}"> <form method="POST" action="{{ route('foods.store') }}">
@csrf @csrf
<div class="flex flex-col space-y-4"> <div class="flex flex-col space-y-4">
<div class="grid grid-cols-2 gap-4"> <div class="grid grid-cols-2 gap-4">

View File

@ -1,7 +1,7 @@
<x-app-layout> <x-app-layout>
<x-slot name="header"> <x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight"> <h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Ingredients') }} {{ __('Foods') }}
</h2> </h2>
</x-slot> </x-slot>
@ -15,34 +15,34 @@
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200"> <div class="p-6 bg-white border-b border-gray-200">
<div class="grid grid-cols-3 gap-4"> <div class="grid grid-cols-3 gap-4">
@foreach ($ingredients as $ingredient) @foreach ($foods as $food)
<div class="p-2 font-light rounded-lg border-2 border-gray-200"> <div class="p-2 font-light rounded-lg border-2 border-gray-200">
<div class="pb-2 lowercase flex justify-between items-baseline"> <div class="pb-2 lowercase flex justify-between items-baseline">
<div class="text-2xl"> <div class="text-2xl">
{{ $ingredient->name }}@if($ingredient->detail), <span class="text-gray-500">{{ $ingredient->detail }}</span>@endif {{ $food->name }}@if($food->detail), <span class="text-gray-500">{{ $food->detail }}</span>@endif
</div> </div>
<div class="text-right text-sm"> <div class="text-right text-sm">
@if ($ingredient->unit_weight) @if ($food->unit_weight)
{{ $ingredient->unit_weight }}g each {{ $food->unit_weight }}g each
@else @else
{{ $ingredient->cup_weight }}g per cup {{ $food->cup_weight }}g per cup
@endif @endif
</div> </div>
</div> </div>
<div class="grid grid-cols-2 text-sm border-t-8 border-black pt-2"> <div class="grid grid-cols-2 text-sm border-t-8 border-black pt-2">
<div class="col-span-2 text-xs text-right">Amount per 100g</div> <div class="col-span-2 text-xs text-right">Amount per 100g</div>
<div class="font-extrabold text-lg border-b-4 border-black">Calories</div> <div class="font-extrabold text-lg border-b-4 border-black">Calories</div>
<div class="font-extrabold text-right text-lg border-b-4 border-black">{{$ingredient->calories}}</div> <div class="font-extrabold text-right text-lg border-b-4 border-black">{{$food->calories}}</div>
<div class="font-bold border-b border-gray-300">Fat</div> <div class="font-bold border-b border-gray-300">Fat</div>
<div class="text-right border-b border-gray-300">{{ $ingredient->fat < 1 ? $ingredient->fat * 1000 . "m" : $ingredient->fat }}g</div> <div class="text-right border-b border-gray-300">{{ $food->fat < 1 ? $food->fat * 1000 . "m" : $food->fat }}g</div>
<div class="font-bold border-b border-gray-300">Cholesterol</div> <div class="font-bold border-b border-gray-300">Cholesterol</div>
<div class="text-right border-b border-gray-300">{{ $ingredient->cholesterol < 1 ? $ingredient->cholesterol * 1000 . "m" : $ingredient->cholesterol }}g</div> <div class="text-right border-b border-gray-300">{{ $food->cholesterol < 1 ? $food->cholesterol * 1000 . "m" : $food->cholesterol }}g</div>
<div class="font-bold border-b border-gray-300">Sodium</div> <div class="font-bold border-b border-gray-300">Sodium</div>
<div class="text-right border-b border-gray-300">{{ $ingredient->sodium < 1 ? $ingredient->sodium * 1000 . "m" : $ingredient->sodium }}g</div> <div class="text-right border-b border-gray-300">{{ $food->sodium < 1 ? $food->sodium * 1000 . "m" : $food->sodium }}g</div>
<div class="font-bold border-b border-gray-300">Carbohydrates</div> <div class="font-bold border-b border-gray-300">Carbohydrates</div>
<div class="text-right border-b border-gray-300">{{ $ingredient->carbohydrates < 1 ? $ingredient->carbohydrates * 1000 . "m" : $ingredient->carbohydrates }}g</div> <div class="text-right border-b border-gray-300">{{ $food->carbohydrates < 1 ? $food->carbohydrates * 1000 . "m" : $food->carbohydrates }}g</div>
<div class="font-bold">Protein</div> <div class="font-bold">Protein</div>
<div class="text-right">{{ $ingredient->protein < 1 ? $ingredient->protein * 1000 . "m" : $ingredient->protein }}g</div> <div class="text-right">{{ $food->protein < 1 ? $food->protein * 1000 . "m" : $food->protein }}g</div>
</div> </div>
</div> </div>
@endforeach @endforeach

View File

@ -43,12 +43,12 @@
</x-dropdown> </x-dropdown>
</div> </div>
<!-- Ingredients Dropdown --> <!-- Foods Dropdown -->
<div class="hidden sm:flex sm:items-center sm:ml-6"> <div class="hidden sm:flex sm:items-center sm:ml-6">
<x-dropdown align="left" width="48"> <x-dropdown align="left" width="48">
<x-slot name="trigger"> <x-slot name="trigger">
<button class="flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out"> <button class="flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out">
<div>Ingredients</div> <div>Foods</div>
<div class="ml-1"> <div class="ml-1">
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"> <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
@ -59,11 +59,11 @@
</x-slot> </x-slot>
<x-slot name="content"> <x-slot name="content">
<x-dropdown-link :href="route('ingredients.create')"> <x-dropdown-link :href="route('foods.create')">
{{ __('Add Ingredient') }} {{ __('Add Food') }}
</x-dropdown-link> </x-dropdown-link>
<x-dropdown-link :href="route('ingredients.index')"> <x-dropdown-link :href="route('foods.index')">
{{ __('List Ingredients') }} {{ __('List Foods') }}
</x-dropdown-link> </x-dropdown-link>
</x-slot> </x-slot>
</x-dropdown> </x-dropdown>

View File

@ -69,17 +69,17 @@
@for($i = 0; $i < 10; $i++) @for($i = 0; $i < 10; $i++)
<div class="flex flex-row space-x-4 mb-4"> <div class="flex flex-row space-x-4 mb-4">
<x-inputs.input type="number" <x-inputs.input type="number"
name="ingredients_amount[]" name="foods_amount[]"
:value="old('ingredients_amount.' . $i)" :value="old('foods_amount.' . $i)"
step="any" /> step="any" />
<x-inputs.select name="ingredients_unit[]" <x-inputs.select name="foods_unit[]"
:options="$ingredient_units" :options="$food_units"
:selectedValue="old('ingredients_unit.' . $i)"> :selectedValue="old('foods_unit.' . $i)">
<option value=""></option> <option value=""></option>
</x-inputs.select> </x-inputs.select>
<x-inputs.select name="ingredients[]" <x-inputs.select name="foods[]"
:options="$ingredients" :options="$foods"
:selectedValue="old('ingredients.' . $i)"> :selectedValue="old('foods.' . $i)">
<option value=""></option> <option value=""></option>
</x-inputs.select> </x-inputs.select>
</div> </div>

View File

@ -11,11 +11,11 @@
<h3 class="mb-2 font-bold">Description</h3> <h3 class="mb-2 font-bold">Description</h3>
<div class="text-gray-800">{{ $recipe->description }}</div> <div class="text-gray-800">{{ $recipe->description }}</div>
<h3 class="mb-2 mt-4 font-bold">Ingredients</h3> <h3 class="mb-2 mt-4 font-bold">Ingredients</h3>
@foreach($recipe->ingredientAmounts as $ia) @foreach($recipe->foodAmounts as $ia)
<div class="flex flex-row space-x-2 mb-2"> <div class="flex flex-row space-x-2 mb-2">
<div>{{ $ia->amount }}</div> <div>{{ $ia->amount }}</div>
@if($ia->unit)<div>{{ $ia->unit }}</div>@endif @if($ia->unit)<div>{{ $ia->unit }}</div>@endif
<div>{{ $ia->ingredient->name }}</div> <div>{{ $ia->food->name }}</div>
</div> </div>
@endforeach @endforeach
<h3 class="mb-2 mt-4 font-bold">Steps</h3> <h3 class="mb-2 mt-4 font-bold">Steps</h3>

View File

@ -20,13 +20,13 @@ Route::middleware('auth:api')->get('/user', function (Request $request) {
}); });
JsonApi::register('default')->routes(function ($api) { JsonApi::register('default')->routes(function ($api) {
$api->resource('ingredient-amounts')->relationships(function ($relations) { $api->resource('food-amounts')->relationships(function ($relations) {
$relations->hasOne('ingredient'); $relations->hasOne('food');
$relations->hasOne('recipe'); $relations->hasOne('recipe');
}); });
$api->resource('ingredients'); $api->resource('foods');
$api->resource('recipes')->relationships(function ($relations) { $api->resource('recipes')->relationships(function ($relations) {
$relations->hasMany('ingredient-amounts'); $relations->hasMany('food-amounts');
$relations->hasOne('steps'); $relations->hasOne('steps');
}); });
$api->resource('recipe-steps')->relationships(function ($relations) { $api->resource('recipe-steps')->relationships(function ($relations) {

View File

@ -1,6 +1,6 @@
<?php <?php
use App\Http\Controllers\IngredientController; use App\Http\Controllers\FoodController;
use App\Http\Controllers\RecipeController; use App\Http\Controllers\RecipeController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
@ -23,7 +23,7 @@ Route::get('/dashboard', function () {
return view('dashboard'); return view('dashboard');
})->middleware(['auth'])->name('dashboard'); })->middleware(['auth'])->name('dashboard');
Route::resource('ingredients', IngredientController::class); Route::resource('foods', FoodController::class);
Route::resource('recipes', RecipeController::class); Route::resource('recipes', RecipeController::class);
require __DIR__.'/auth.php'; require __DIR__.'/auth.php';