Laravel - где проверять последние записи отношений без проверки других - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть две таблицы, которые имеют отношение один ко многим.

Заказы - (id)

booking_tasks - (id, booking_id,user_id)

одно бронирование имеет много задач одно задание имеет одно бронирование

Модель бронирования:

 public function tasks() {
    return $this->hasMany('App\BookingTask');    
  }

BookingTask Модель

public function booking() {
    return $this->belongsTo('App\Booking');
} 

Я хочу получить список бронирований, user_id = 2 для последнего booking_task для заказов. Я не хочу проверять другие старые booking_tasks заказов.

например:

enter image description here

Я хочу проверить, является ли последняя запись user_id в booking_task = 2, а затем получить ее в качестве бронирования. В приведенном примере последний параметр booking_task's user_id = 5. Таким образом, он не будет получен в качестве бронирования.

Мой код:

$bookings=Booking::whereHas('tasks',function($q){
            $q->where('user_id',2);//this will check whether any of record has user_id =2
})->get();

Я также использовал это: Но это не правильно,

$bookings=Booking::whereHas('tasks',function($q){
                $q->latest()->where('user_id',2)->limit(1);//this will check whether any of record has user_id =2 and return latest one.
    })->get();

Как я могу решить эту проблему, я должен также использовать Laravel Eloquent.

Ответы [ 4 ]

0 голосов
/ 24 января 2019

Я обнаружил, что ответ от Джонаса сработал, но поскольку это был запрос с объединением, это вызвало проблемы с готовностью загружать отношения из модели. Поэтому я использовал это решение с функцией 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');
});

Это та же логика, что и принятого ответа, но ее немного проще использовать повторно. Это будет, однако, немного медленнее, но это должно стоить повторного использования.

0 голосов
/ 02 ноября 2018

Это

Я хочу получить список бронирований, user_id = 2 для последнего booking_task для бронирований. Я не хочу проверять другие старые booking_tasks заказов.

не имеет большого смысла, но я думаю, что вы хотите получить, это все заказы с user_id == 2, где есть хотя бы 1 задача и с только самое последнее задание для каждого бронирования? Так что, возможно, это сработает?

Booking::where('user_id', 2)->with('tasks', function($query){
    $query->orderBy('created_at', 'DESC')->take(1);
})->has('tasks')->get();
0 голосов
/ 02 ноября 2018

Для этого требуется более сложный запрос:

$bookings = Booking::select('bookings.*')
    ->join('booking_tasks', 'bookings.id', 'booking_tasks.booking_id')
    ->where('booking_tasks.user_id', 2)
    ->where('booking_tasks.id', function($query) {
        $query->select('id')
            ->from('booking_tasks')
            ->whereColumn('booking_id', 'bookings.id')
            ->latest()
            ->limit(1);
    })->get();
0 голосов
/ 02 ноября 2018

Вы пробовали -> first () в сочетании с обратным orderBy ()?

Как $ q-> где (‘user_id’, ’=‘, ’2’) -> orderBy (‘id’, ’DESC’) -> first ();

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