Я обнаружил, что ответ от Джонаса сработал, но поскольку это был запрос с объединением, это вызвало проблемы с готовностью загружать отношения из модели. Поэтому я использовал это решение с функцией whereHas
, чтобы придумать решение, которое можно было бы использовать в областях и, таким образом, можно использовать повторно.
Первый шаг включает добавление макроса к запросу Builder
в AppServiceProvider
.
use Illuminate\Database\Query\Builder;
Builder::macro('whereLatestRelation', function ($table, $parentRelatedColumn)
{
return $this->where($table . '.id', function ($sub) use ($table, $parentRelatedColumn) {
$sub->select('id')
->from($table . ' AS other')
->whereColumn('other.' . $parentRelatedColumn, $table . '.' . $parentRelatedColumn)
->latest()
->take(1);
});
});
Это в основном делает подзапросную часть ответа Джонаса более общей, позволяя вам указать таблицу соединений и столбец, к которому они присоединяются. Предполагается, что другой столбец является столбцом id, поэтому его можно улучшить еще больше. Чтобы использовать это, вы сможете:
$userId = 2;
Booking::whereHas('tasks', function ($tasks) use ($userId) {
$tasks->where('user_id', $userId)
->whereLatestRelation((new Task)->getTable(), 'booking_id');
});
Это та же логика, что и принятого ответа, но ее немного проще использовать повторно. Это будет, однако, немного медленнее, но это должно стоить повторного использования.