Add API endpoint and relationships for recipe separators

This commit is contained in:
Christopher C. Wells 2021-03-31 20:48:39 -07:00 committed by Christopher Charbonneau Wells
parent 91af802c2f
commit e97056553a
8 changed files with 174 additions and 7 deletions

View File

@ -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.
*/

View File

@ -0,0 +1,53 @@
<?php
namespace App\JsonApi\Adapters;
use App\Models\RecipeSeparator;
use CloudCreativity\LaravelJsonApi\Eloquent\AbstractAdapter;
use CloudCreativity\LaravelJsonApi\Eloquent\BelongsTo;
use CloudCreativity\LaravelJsonApi\Pagination\StandardStrategy;
use Illuminate\Support\Collection;
class RecipeSeparatorAdapter extends AbstractAdapter
{
/**
* {@inheritdoc}
*/
protected $attributes = [];
/**
* {@inheritdoc}
*/
protected $filterScopes = [];
/**
* {@inheritdoc}
*/
protected $defaultSort = ['weight'];
/**
* {@inheritdoc}
*/
public function __construct(StandardStrategy $paging)
{
parent::__construct(new RecipeSeparator(), $paging);
}
/**
* {@inheritdoc}
*/
protected function filter($query, Collection $filters)
{
$this->filterWithScopes($query, $filters);
}
/**
* Recipe relationship.
*/
protected function recipe(): BelongsTo
{
return $this->belongsTo();
}
}

View File

@ -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) {

View File

@ -0,0 +1,49 @@
<?php
namespace App\JsonApi\Schemas;
use Neomerx\JsonApi\Schema\SchemaProvider;
class RecipeSeparatorSchema extends SchemaProvider
{
/**
* {@inheritdoc}
*/
protected $resourceType = 'recipe-separators';
/**
* {@inheritdoc}
*/
public function getId($resource): string
{
return (string) $resource->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,
]
];
}
}

View File

@ -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');
}

View File

@ -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,

View File

@ -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();

View File

@ -0,0 +1,38 @@
<?php
namespace Tests\Feature\JsonApi;
use App\Models\Recipe;
use App\Models\RecipeSeparator;
use Database\Factories\RecipeSeparatorFactory;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Foundation\Testing\RefreshDatabase;
class RecipeSeparatorApiTest extends JsonApiTestCase
{
use RefreshDatabase;
/**
* @inheritdoc
*/
public function factory(): RecipeSeparatorFactory
{
return RecipeSeparator::factory();
}
/**
* @inheritdoc
*/
public function resourceName(): string
{
return 'recipe-separators';
}
/**
* @inheritdoc
*/
protected function createInstances(int $count = 1): Collection {
return Recipe::factory()->count(1)->hasSeparators($count)->create();
}
}