From e97056553abc5c2393d92bcc6c959c9f707ae77f Mon Sep 17 00:00:00 2001 From: "Christopher C. Wells" Date: Wed, 31 Mar 2021 20:48:39 -0700 Subject: [PATCH] Add API endpoint and relationships for recipe separators --- app/JsonApi/Adapters/RecipeAdapter.php | 8 +++ .../Adapters/RecipeSeparatorAdapter.php | 53 +++++++++++++++++++ app/JsonApi/Schemas/RecipeSchema.php | 11 ++-- app/JsonApi/Schemas/RecipeSeparatorSchema.php | 49 +++++++++++++++++ app/Models/Recipe.php | 17 ++++-- config/json-api-v1.php | 1 + routes/api.php | 4 ++ .../JsonApi/RecipeSeparatorApiTest.php | 38 +++++++++++++ 8 files changed, 174 insertions(+), 7 deletions(-) create mode 100644 app/JsonApi/Adapters/RecipeSeparatorAdapter.php create mode 100644 app/JsonApi/Schemas/RecipeSeparatorSchema.php create mode 100644 tests/Feature/JsonApi/RecipeSeparatorApiTest.php diff --git a/app/JsonApi/Adapters/RecipeAdapter.php b/app/JsonApi/Adapters/RecipeAdapter.php index 7d14300..abc4bb3 100644 --- a/app/JsonApi/Adapters/RecipeAdapter.php +++ b/app/JsonApi/Adapters/RecipeAdapter.php @@ -70,6 +70,14 @@ class RecipeAdapter extends AbstractAdapter return $this->morphMany($this->hasMany('media')); } + /** + * Ingredient amount relationships. + */ + protected function separators(): HasMany + { + return $this->hasMany(); + } + /** * Step relationships. */ diff --git a/app/JsonApi/Adapters/RecipeSeparatorAdapter.php b/app/JsonApi/Adapters/RecipeSeparatorAdapter.php new file mode 100644 index 0000000..4da07c2 --- /dev/null +++ b/app/JsonApi/Adapters/RecipeSeparatorAdapter.php @@ -0,0 +1,53 @@ +filterWithScopes($query, $filters); + } + + /** + * Recipe relationship. + */ + protected function recipe(): BelongsTo + { + return $this->belongsTo(); + } + +} diff --git a/app/JsonApi/Schemas/RecipeSchema.php b/app/JsonApi/Schemas/RecipeSchema.php index 1360165..8979d5f 100644 --- a/app/JsonApi/Schemas/RecipeSchema.php +++ b/app/JsonApi/Schemas/RecipeSchema.php @@ -62,7 +62,6 @@ class RecipeSchema extends SchemaProvider { return [ 'ingredient-amounts' => [ - self::SHOW_SELF => true, self::SHOW_RELATED => true, self::SHOW_DATA => isset($includeRelationships['ingredient-amounts']), self::DATA => function () use ($resource) { @@ -70,15 +69,20 @@ class RecipeSchema extends SchemaProvider }, ], 'media' => [ - self::SHOW_SELF => true, self::SHOW_RELATED => true, self::SHOW_DATA => isset($includeRelationships['media']), self::DATA => function () use ($resource) { return $resource->media; }, ], + 'separators' => [ + self::SHOW_RELATED => true, + self::SHOW_DATA => isset($includeRelationships['separators']), + self::DATA => function () use ($resource) { + return $resource->separators; + }, + ], 'steps' => [ - self::SHOW_SELF => true, self::SHOW_RELATED => true, self::SHOW_DATA => isset($includeRelationships['steps']), self::DATA => function () use ($resource) { @@ -86,7 +90,6 @@ class RecipeSchema extends SchemaProvider }, ], 'tags' => [ - self::SHOW_SELF => true, self::SHOW_RELATED => true, self::SHOW_DATA => isset($includeRelationships['tags']), self::DATA => function () use ($resource) { diff --git a/app/JsonApi/Schemas/RecipeSeparatorSchema.php b/app/JsonApi/Schemas/RecipeSeparatorSchema.php new file mode 100644 index 0000000..626cb7d --- /dev/null +++ b/app/JsonApi/Schemas/RecipeSeparatorSchema.php @@ -0,0 +1,49 @@ +getRouteKey(); + } + + /** + * {@inheritdoc} + */ + public function getAttributes($resource): array + { + return [ + 'container' => $resource->container, + 'weight' => $resource->weight, + 'text' => $resource->text, + 'createdAt' => $resource->created_at, + 'updatedAt' => $resource->updated_at, + ]; + } + + /** + * @inheritdoc + */ + public function getRelationships($resource, $isPrimary, array $includeRelationships): array + { + return [ + 'recipe' => [ + self::SHOW_SELF => true, + self::SHOW_RELATED => true, + ] + ]; + } +} diff --git a/app/Models/Recipe.php b/app/Models/Recipe.php index 8b6e440..6184263 100644 --- a/app/Models/Recipe.php +++ b/app/Models/Recipe.php @@ -75,6 +75,8 @@ use Spatie\MediaLibrary\MediaCollections\Models\Media; * @method static \Database\Factories\RecipeFactory factory(...$parameters) * @method static \Illuminate\Database\Eloquent\Builder|Recipe whereTimeCook($value) * @property-read Collection $ingredients_list + * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\RecipeSeparator[] $separators + * @property-read int|null $separators_count */ final class Recipe extends Model implements HasMedia { @@ -182,14 +184,23 @@ final class Recipe extends Model implements HasMedia } /** - * Get "separators" for the ingredients. + * Get "separators" for the recipe. * - * Separators are used to adding headings or simple separations to the + * Separators are used to add headings or simple separations to the * ingredients _list_ for a recipe. Their position is defined by weights * compatible with ingredient weights. + * + * @todo Add support for step separators + */ + public function separators(): HasMany { + return $this->hasMany(RecipeSeparator::class); + } + + /** + * Get ingredient separators. */ public function ingredientSeparators(): HasMany { - return $this->hasMany(RecipeSeparator::class) + return $this->separators() ->where('container', 'ingredients') ->orderBy('weight'); } diff --git a/config/json-api-v1.php b/config/json-api-v1.php index bef6db0..ecc98a7 100644 --- a/config/json-api-v1.php +++ b/config/json-api-v1.php @@ -71,6 +71,7 @@ return [ 'media' => \Spatie\MediaLibrary\MediaCollections\Models\Media::class, 'journal-entries' => \App\Models\JournalEntry::class, 'recipes' => \App\Models\Recipe::class, + 'recipe-separators' => \App\Models\RecipeSeparator::class, 'recipe-steps' => \App\Models\RecipeStep::class, 'tags' => \App\Models\Tag::class, 'users' => \App\Models\User::class, diff --git a/routes/api.php b/routes/api.php index 759c2ab..fae9922 100644 --- a/routes/api.php +++ b/routes/api.php @@ -30,9 +30,13 @@ JsonApi::register('v1')->routes(function ($api) { $api->resource('recipes')->relationships(function ($relations) { $relations->hasMany('ingredient-amounts')->readOnly(); $relations->hasMany('media')->readOnly(); + $relations->hasMany('separators')->readOnly(); $relations->hasMany('steps')->readOnly(); $relations->hasMany('tags')->readOnly(); })->readOnly(); + $api->resource('recipe-separators')->relationships(function ($relations) { + $relations->hasOne('recipe')->readOnly(); + })->readOnly(); $api->resource('recipe-steps')->relationships(function ($relations) { $relations->hasOne('recipe')->readOnly(); })->readOnly(); diff --git a/tests/Feature/JsonApi/RecipeSeparatorApiTest.php b/tests/Feature/JsonApi/RecipeSeparatorApiTest.php new file mode 100644 index 0000000..ef2bedf --- /dev/null +++ b/tests/Feature/JsonApi/RecipeSeparatorApiTest.php @@ -0,0 +1,38 @@ +count(1)->hasSeparators($count)->create(); + } + +}