Add custom serving name field to foods

This commit is contained in:
Christopher C. Wells 2021-02-03 21:39:52 -08:00 committed by Christopher Charbonneau Wells
parent 3d81634556
commit afa4e5f93f
10 changed files with 90 additions and 8 deletions

View File

@ -83,6 +83,7 @@ class FoodController extends Controller
'notes' => 'nullable|string',
'serving_size' => ['required', new StringIsDecimalOrFraction],
'serving_unit' => 'nullable|string',
'serving_unit_name' => 'nullable|string',
'serving_weight' => 'required|numeric',
'calories' => 'nullable|numeric',
'fat' => 'nullable|numeric',
@ -93,7 +94,7 @@ class FoodController extends Controller
]);
$attributes['serving_size'] = Number::floatFromString($attributes['serving_size']);
$attributes['name'] = Str::lower($attributes['name']);
$food->fill(array_filter($attributes))->save();
$food->fill($attributes)->save();
// Sync tags.
if ($tags = $request->get('tags')) {

View File

@ -41,6 +41,7 @@ class FoodSchema extends SchemaProvider
'servingSize' => $resource->serving_size,
'servingSizeFormatted' => $resource->serving_size_formatted,
'servingUnit' => $resource->serving_unit,
'servingUnitFormatted' => $resource->serving_unit_formatted,
'servingWeight' => $resource->serving_weight,
'createdAt' => $resource->created_at,
'updatedAt' => $resource->updated_at,

View File

@ -96,6 +96,7 @@ final class Food extends Model
'sodium',
'serving_size',
'serving_unit',
'serving_unit_name',
'serving_weight',
];
@ -116,7 +117,10 @@ final class Food extends Model
/**
* @inheritdoc
*/
protected $appends = ['serving_size_formatted'];
protected $appends = [
'serving_size_formatted',
'serving_unit_formatted'
];
/**
* Get the serving size as a formatted string (e.g. 0.5 = 1/2).
@ -125,4 +129,15 @@ final class Food extends Model
return Number::fractionStringFromFloat($this->serving_size);
}
/**
* Get the "formatted" serving unit (for custom unit support).
*/
public function getServingUnitFormattedAttribute(): ?string {
$unit = $this->serving_unit;
if (empty($unit)) {
$unit = $this->serving_unit_name ?? null;
}
return $unit;
}
}

View File

@ -7,6 +7,7 @@ use App\Support\Nutrients;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Pluralizer;
/**
* App\Models\IngredientAmount
@ -83,7 +84,7 @@ final class IngredientAmount extends Model
/**
* @inheritdoc
*/
protected $appends = ['amount_formatted'];
protected $appends = ['amount_formatted', 'unit_formatted'];
/**
* Get the amount as a formatted string (e.g. 0.5 = 1/2).
@ -92,6 +93,26 @@ final class IngredientAmount extends Model
return Number::fractionStringFromFloat($this->amount);
}
/**
* Get a "formatted" unit.
*
* @see \App\Models\Food::getServingUnitFormattedAttribute()
*/
public function getUnitFormattedAttribute(): ?string {
$unit = $this->unit;
// Inherit formatted unit from Food.
if ($unit === 'serving' && $this->ingredient->type === Food::class) {
$unit = $this->ingredient->serving_unit_formatted;
}
if ($unit && $unit != 'tsp' && $unit != 'tbsp') {
$unit = Pluralizer::plural($unit, ceil($this->amount));
}
return $unit;
}
/**
* Get the ingredient type (Food or Recipe).
*/

View File

@ -16,7 +16,7 @@ trait Ingredient
}
/**
* Gets the class name.
* Get the class name.
*
* This is necessary e.g. to provide data in ingredient picker responses.
*/
@ -32,7 +32,7 @@ trait Ingredient
}
/**
* Gets search results for a term.
* Get search results for a term.
*/
public static function search(string $term, int $limit = 10): Collection {
return (new static)::where('name', 'like', "%{$term}%")->limit($limit)->get();

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddServingUnitNameFieldToFoods extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('foods', function (Blueprint $table) {
$table->string('serving_unit_name')->nullable()->after('serving_unit');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('foods', function (Blueprint $table) {
$table->dropColumn(['serving_unit_name']);
});
}
}

View File

@ -82,6 +82,18 @@
</x-inputs.select>
</div>
<!-- Serving unit name -->
<div>
<x-inputs.label for="serving_unit_name" value="Serving unit name"/>
<x-inputs.input name="serving_unit_name"
placeholder="e.g. clove, egg"
class="block mt-1 w-full"
type="text"
size="10"
:value="old('serving_unit_name', $food->serving_unit_name)"/>
</div>
<!-- Serving weight -->
<div>
<x-inputs.label for="serving_weight" value="Serving weight (g)"/>

View File

@ -30,7 +30,7 @@
<div>Serving size</div>
<div>
<span x-text="food.servingSizeFormatted"></span>
<span x-text="food.servingUnit ?? 'unit'"></span>
<span x-text="food.servingUnitFormatted ?? food.name"></span>
<span x-text="`(${food.servingWeight}g)`"></span>
</div>
</div>

View File

@ -34,7 +34,7 @@
<div>Serving size</div>
<div>
{{ $food->servingSizeFormatted }}
{{ $food->serving_unit }}
{{ $food->servingUnitFormatted ?? $food->name }}
({{ $food->serving_weight }}g)
</div>
</div>

View File

@ -31,7 +31,7 @@
@foreach($recipe->ingredientAmounts as $ia)
<div class="flex flex-row space-x-2 mb-2">
<div>{{ \App\Support\Number::fractionStringFromFloat($ia->amount) }}</div>
@if($ia->unit)<div>{{ $ia->unit }}</div>@endif
@if($ia->unitFormatted)<div>{{ $ia->unitFormatted }}</div>@endif
<div>
@if($ia->ingredient->type === \App\Models\Recipe::class)
<a class="text-gray-500 hover:text-gray-700 hover:border-gray-300"