diff --git a/app/Models/Food.php b/app/Models/Food.php index c285d52..1f5f606 100644 --- a/app/Models/Food.php +++ b/app/Models/Food.php @@ -3,7 +3,6 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Database\Eloquent\Model; /** * @property int id @@ -22,7 +21,7 @@ use Illuminate\Database\Eloquent\Model; * @property \Illuminate\Support\Carbon created_at * @property \Illuminate\Support\Carbon updated_at */ -class Food extends Model +class Food extends JournalableModel { use HasFactory; diff --git a/app/Models/JournalEntry.php b/app/Models/JournalEntry.php index acf767d..3f02694 100644 --- a/app/Models/JournalEntry.php +++ b/app/Models/JournalEntry.php @@ -5,9 +5,19 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\MorphToMany; /** - * TODO: Change this model to track nutrients _directly_. + * @property int id + * @property \Illuminate\Support\Carbon date + * @property string summary + * @property float calories + * @property float carbohydrates + * @property float cholesterol + * @property float fat + * @property float protein + * @property float sodium + * @property string meal */ class JournalEntry extends Model { @@ -17,38 +27,34 @@ class JournalEntry extends Model * @inheritdoc */ protected $fillable = [ + 'calories', + 'carbohydrates', + 'cholesterol', 'date', - 'servings', - 'amount', - 'unit', + 'fat', + 'meal', + 'protein', + 'sodium', + 'summary', ]; /** * The attributes that should be cast. */ protected $casts = [ + 'calories' => 'float', + 'carbohydrates' => 'float', + 'cholesterol' => 'float', 'date' => 'datetime:Y-m-d', - 'amount' => 'float', + 'fat' => 'float', + 'protein' => 'float', + 'sodium' => 'float', ]; /** * @inheritdoc */ - protected $with = ['recipe', 'food', 'user']; - - /** - * Get the Recipe this entry belongs to. - */ - public function recipe(): BelongsTo { - return $this->belongsTo(Recipe::class); - } - - /** - * Get the Food this entry belongs to. - */ - public function food(): BelongsTo { - return $this->belongsTo(Food::class); - } + protected $with = ['user', 'foods', 'recipes']; /** * Get the User this entry belongs to. @@ -57,4 +63,18 @@ class JournalEntry extends Model return $this->belongsTo(User::class); } + /** + * Get all recipes related to this entry. + */ + public function foods(): MorphToMany { + return $this->morphedByMany(Food::class, 'journalable'); + } + + /** + * Get all recipes related to this entry. + */ + public function recipes(): MorphToMany { + return $this->morphedByMany(Recipe::class, 'journalable'); + } + } diff --git a/app/Models/JournalableModel.php b/app/Models/JournalableModel.php new file mode 100644 index 0000000..ffd6b2f --- /dev/null +++ b/app/Models/JournalableModel.php @@ -0,0 +1,16 @@ +morphToMany(JournalEntry::class, 'journalable'); + } +} diff --git a/app/Models/Recipe.php b/app/Models/Recipe.php index 383bd8b..2a7d531 100644 --- a/app/Models/Recipe.php +++ b/app/Models/Recipe.php @@ -3,7 +3,6 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; /** @@ -28,7 +27,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; * @method float sodiumTotal Get total sodium. * @method float sodiumPerServing Get per serving sodium. */ -class Recipe extends Model +class Recipe extends JournalableModel { use HasFactory; diff --git a/database/migrations/2020_12_21_215527_create_food_amounts_table.php b/database/migrations/2020_12_21_215527_create_food_amounts_table.php index cadca79..22782e9 100644 --- a/database/migrations/2020_12_21_215527_create_food_amounts_table.php +++ b/database/migrations/2020_12_21_215527_create_food_amounts_table.php @@ -17,10 +17,10 @@ class CreateFoodAmountsTable extends Migration { Schema::create('food_amounts', function (Blueprint $table) { $table->id(); - $table->foreignIdFor(Food::class); + $table->foreignIdFor(Food::class)->index(); $table->unsignedFloat('amount'); $table->enum('unit', ['tsp', 'tbsp', 'cup', 'oz'])->nullable(); - $table->foreignIdFor(Recipe::class); + $table->foreignIdFor(Recipe::class)->index(); $table->unsignedInteger('weight'); $table->timestamps(); }); diff --git a/database/migrations/2020_12_22_051133_create_recipe_steps_table.php b/database/migrations/2020_12_22_051133_create_recipe_steps_table.php index ef2ee08..3a89613 100644 --- a/database/migrations/2020_12_22_051133_create_recipe_steps_table.php +++ b/database/migrations/2020_12_22_051133_create_recipe_steps_table.php @@ -20,6 +20,7 @@ class CreateRecipeStepsTable extends Migration $table->unsignedInteger('number'); $table->longText('step'); $table->timestamps(); + $table->index('recipe_id', 'number'); }); } diff --git a/database/migrations/2020_12_31_180016_create_journal_entries_table.php b/database/migrations/2020_12_31_180016_create_journal_entries_table.php index 9075d64..d896c19 100644 --- a/database/migrations/2020_12_31_180016_create_journal_entries_table.php +++ b/database/migrations/2020_12_31_180016_create_journal_entries_table.php @@ -1,7 +1,5 @@ id(); $table->foreignIdFor(User::class); - $table->foreignIdFor(Food::class)->nullable(); - $table->foreignIdFor(Recipe::class)->nullable(); $table->date('date')->useCurrent(); - $table->unsignedFloat('amount'); - $table->enum('unit', ['tsp', 'tbsp', 'cup', 'grams', 'serving'])->nullable(); + $table->string('summary'); + $table->unsignedFloat('calories')->default(0); + $table->unsignedFloat('fat')->default(0); + $table->unsignedFloat('cholesterol')->default(0); + $table->unsignedFloat('sodium')->default(0); + $table->unsignedFloat('carbohydrates')->default(0); + $table->unsignedFloat('protein')->default(0); $table->enum('meal', ['breakfast', 'lunch', 'dinner', 'snacks']); $table->timestamps(); + $table->index(['user_id', 'date']); }); } diff --git a/database/migrations/2021_01_01_170724_create_journalables_table.php b/database/migrations/2021_01_01_170724_create_journalables_table.php new file mode 100644 index 0000000..a3c0cf7 --- /dev/null +++ b/database/migrations/2021_01_01_170724_create_journalables_table.php @@ -0,0 +1,33 @@ +foreignIdFor(JournalEntry::class)->index(); + $table->unsignedInteger('journalable_id'); + $table->string('journalable_type'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('journalables'); + } +} diff --git a/database/seeders/JournalEntrySeeder.php b/database/seeders/JournalEntrySeeder.php index 52b76dc..4cf0b85 100644 --- a/database/seeders/JournalEntrySeeder.php +++ b/database/seeders/JournalEntrySeeder.php @@ -6,8 +6,9 @@ use App\Models\Food; use App\Models\JournalEntry; use App\Models\Recipe; use App\Models\User; -use Carbon\Carbon; use Illuminate\Database\Seeder; +use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\DB; class JournalEntrySeeder extends Seeder { @@ -18,49 +19,110 @@ class JournalEntrySeeder extends Seeder */ public function run() { + /** @var \App\Models\Food[] $foods */ + foreach (['peanut butter', 'milk', 'egg', 'raisins'] as $name) { + $foods[$name] = Food::where('name', $name)->first(); + } + + /** @var \App\Models\Recipe $recipe */ + $recipe = Recipe::all()->first(); + /** @var \App\Models\User $user */ $user = User::all()->first; + $default_entries = [ [ 'user_id' => $user->id, - 'food_id' => Food::where('name', 'milk')->first()->id, 'date' => Carbon::now()->toDateString(), - 'amount' => 2, - 'unit' => 'cup', + 'summary' => '2 egg, 1 serving milk', + 'calories' => $foods['egg']->calories * 2 + $foods['milk']->calories, + 'fat' => $foods['egg']->fat * 2 + $foods['milk']->fat, + 'cholesterol' => $foods['egg']->cholesterol * 2 + $foods['milk']->cholesterol, + 'sodium' => $foods['egg']->sodium * 2 + $foods['milk']->sodium, + 'carbohydrates' => $foods['egg']->carbohydrates * 2 + $foods['milk']->carbohydrates, + 'protein' => $foods['egg']->protein * 2 + $foods['milk']->protein, 'meal' => 'breakfast', ], [ 'user_id' => $user->id, - 'food_id' => Food::where('name', 'egg')->first()->id, 'date' => Carbon::now()->toDateString(), - 'amount' => 3, - 'meal' => 'breakfast', - ], - [ - 'user_id' => $user->id, - 'recipe_id' => Recipe::all()->first(), - 'date' => Carbon::now()->toDateString(), - 'amount' => 1, - 'unit' => 'serving', + 'summary' => '1 serving pancakes', + 'calories' => $recipe->caloriesPerServing(), + 'fat' => $recipe->fatPerServing(), + 'cholesterol' => $recipe->cholesterolPerServing(), + 'sodium' => $recipe->sodiumPerServing(), + 'carbohydrates' => $recipe->carbohydratesPerServing(), + 'protein' => $recipe->proteinPerServing(), 'meal' => 'lunch', ], [ 'user_id' => $user->id, - 'recipe_id' => Recipe::all()->first(), 'date' => Carbon::now()->toDateString(), - 'amount' => 1.5, - 'unit' => 'serving', + 'summary' => '1 serving pancakes', + 'calories' => $recipe->caloriesPerServing(), + 'fat' => $recipe->fatPerServing(), + 'cholesterol' => $recipe->cholesterolPerServing(), + 'sodium' => $recipe->sodiumPerServing(), + 'carbohydrates' => $recipe->carbohydratesPerServing(), + 'protein' => $recipe->proteinPerServing(), 'meal' => 'dinner', ], [ 'user_id' => $user->id, - 'food_id' => Food::where('name', 'peanut butter')->first()->id, 'date' => Carbon::now()->toDateString(), - 'amount' => 2, - 'unit' => 'tbsp', + 'summary' => '1 serving peanut butter', + 'calories' => $foods['peanut butter']->calories, + 'fat' => $foods['peanut butter']->fat, + 'cholesterol' => $foods['peanut butter']->cholesterol, + 'sodium' => $foods['peanut butter']->sodium, + 'carbohydrates' => $foods['peanut butter']->carbohydrates, + 'protein' => $foods['peanut butter']->protein, + 'meal' => 'snacks', + ], + [ + 'user_id' => $user->id, + 'date' => Carbon::now()->toDateString(), + 'summary' => '2 servings raisins', + 'calories' => $foods['raisins']->calories * 2, + 'fat' => $foods['raisins']->fat * 2, + 'cholesterol' => $foods['raisins']->cholesterol * 2, + 'sodium' => $foods['raisins']->sodium * 2, + 'carbohydrates' => $foods['raisins']->carbohydrates * 2, + 'protein' => $foods['raisins']->protein * 2, 'meal' => 'snacks', ], ]; JournalEntry::factory()->createMany($default_entries); + + DB::table('journalables')->insert([ + 'journal_entry_id' => 1, + 'journalable_id' => $foods['egg']->id, + 'journalable_type' => Food::class, + ]); + DB::table('journalables')->insert([ + 'journal_entry_id' => 1, + 'journalable_id' => $foods['milk']->id, + 'journalable_type' => Food::class, + ]); + DB::table('journalables')->insert([ + 'journal_entry_id' => 2, + 'journalable_id' => $recipe->id, + 'journalable_type' => Recipe::class, + ]); + DB::table('journalables')->insert([ + 'journal_entry_id' => 3, + 'journalable_id' => $recipe->id, + 'journalable_type' => Recipe::class, + ]); + DB::table('journalables')->insert([ + 'journal_entry_id' => 4, + 'journalable_id' => $foods['peanut butter']->id, + 'journalable_type' => Food::class, + ]); + DB::table('journalables')->insert([ + 'journal_entry_id' => 5, + 'journalable_id' => $foods['raisins']->id, + 'journalable_type' => Food::class, + ]); } }