我有两个具有一对多关系的表。
预订-(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_tasks。
例如:
我想检查booking_task的user_id = 2的最后一条记录是否可以作为预订。 在示例中,最后一个booking_task的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。
答案 0 :(得分:4)
这需要更复杂的查询:
$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();
答案 1 :(得分:0)
您是否尝试过-> first()与相反的orderBy()组合?
类似于$ q-> where('user_id','=','2')-> orderBy('id','DESC')-> first();
答案 2 :(得分:0)
此
我想获取预订清单,其中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();
答案 3 :(得分:0)
我发现Jonas的答案很有效,但是由于这是一个带有联接的查询,因此引起了从模型中急切加载关系的问题。因此,我将该解决方案与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);
});
});
这基本上使Jonas答案的子查询部分更加通用,使您可以指定联接表和它们联接的列。假设另一列是“ id”列,则可以对其进行进一步改进。要使用此功能,您就可以做到:
$userId = 2;
Booking::whereHas('tasks', function ($tasks) use ($userId) {
$tasks->where('user_id', $userId)
->whereLatestRelation((new Task)->getTable(), 'booking_id');
});
与接受的答案逻辑相同,但重用起来更容易。但是,它会慢一些,但是值得重复使用。