Условные ответы в ресурсах API Laravel Eloquent - PullRequest
0 голосов
/ 13 сентября 2018

Ларавел 5.7. У меня есть модель Audio, с полями id и title. Audio может иметь много AudioVersion с, где AudioVersion имеет id, audio_id (имеется в виду Audio) и url.

Теперь у меня есть две родительские модели, Foo и Bar, которые могут иметь много моделей Audio.

Аудио:

class Audio extends Model
{
    public function versions()
    {
        return $this->hasMany('App\AudioVersion', 'audio_id');
    }
}

аудиоверсия:

class AudioVersion extends Model
{
    public function audio()
    {
        return $this->belongsTo('App\AudioContent');
    }
}

Foo:

class Foo extends Model
{
    public function audioContents()
    {
        return $this->morphToMany('App\Audio', 'audio_contentable', 'audio_contentable');
    }
}

У меня есть ресурс Eloquent API, FooResource, который возвращает Audio объектов:

FooResource:

class FooResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'audio' => AudioResource::collection($this->audioContents),
        ];
    }
}

AudioResource:

class AudioResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'urls' => $this->versions,
        ];
    }
}

Моя проблема в том, что в ключе audio моего FooResource я хочу вернуть только Audio s, которые имеют AudioVersions, связанные с ними. То есть если у меня есть Audio без AudioVersions, я не хочу, чтобы Audio был включен в ключ Foo audio. Я не могу найти способ сделать эту глубокую условную логику в Eloquent / Resources.

Ответы [ 3 ]

0 голосов
/ 13 сентября 2018

В классе FooResource вы можете filter() коллекцию, прежде чем передать ее в метод коллекции.

class FooResource extends JsonResource
{
    public function toArray($request)
    {
        $audioContents = $this->audioContents()->filter(function($audio, $key) {
            return $audio->versions->count();
        }

        return [
            'audio' => AudioResource::collection($audioContents),
        ];
    }
}
0 голосов
/ 13 сентября 2018

В конце я добавил область к Audio:

public function scopeHasVersions($query)
{
    return $query->whereHas('versions');
}

Затем в FooResource:

return [
    'audio' => AudioResource::collection($this->audioContents()->hasVersions()->get()),
];
0 голосов
/ 13 сентября 2018

Вам нужно сделать что-то подобное. Это пример, вам нужно только добавить объединение внутри with, так что будут выбраны только те audios, которые имеют audio versions.

$audioContents = AudioContents::with([
    'audio' => function ($query) use ($SpecificID) {
        return $query->join("audio_versions")
                    ->on("audio_versions.audio_id", "=", "audios.id");
    }
])->get();

Попробуйте и дайте мне знать, если у вас возникнут какие-либо проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...