Laravel雄辩地得到哪里没有空,什么地方不空时搜索哪里

时间:2018-08-30 11:13:08

标签: php laravel laravel-5 eloquent

这个问题真的很难说出来,所以我对标题表示歉意!

可以说我有一个Rooms模型和一个Bookings模型,一个房间可以预订很多。

我正在建立一个带有过滤器的表,并且如果需要预订,我需要能够在预订关系上运行过滤器,否则无论如何都要获取记录。

让我们说我的房间有这样的预订关系

public function latestBooking(){
    return $this->hasOne('App\Models\Bookings', 'room_id', 'id')
    ->orderBy('expiry_date', 'DESC')->limit(1);
}

以上关系为我提供了最新的预订。

我正在像这样运行“空缺”过滤器

if ($request->has('filters.vacant_from')) {
    $rooms = $rooms->whereHas('latestBooking', function ($query) use ($request) {
        $query->where('expiry_date', '<', Carbon::createFromFormat('d/m/Y',$request->input('filters.vacant_from'))->format('Y-m-d'));
    });
}

问题在于,这只会获得已预订并在指定日期之后可用的房间。我需要它能够搜索所有房间,如果确实有预订,请检查到期日期是否在指定的日期之后,如果没有最新的预订,无论如何都可以将其作为空房间获得。

基本上我将如何构造我的过滤器函数,使其像这样运行

搜索所有房间,如果有最新预订,请检查其到期日期是否在指定的日期之后;仅在其真实/空缺时才抓住它;如果没有最新预订,则无论如何都要抓住它空缺

3 个答案:

答案 0 :(得分:3)

关于您的latestBookingRelationship,我对您有个建议。您应该创建另一个关系,并为其添加一个greater than today条件,并可能将其命名为activeLatestBooking

然后,您的最新预订应包括所有预订房间,无论其预订是否处于活动状态。

public function activeLatestBooking(){
        return $this->hasOne('App\Models\Bookings', 'room_id', 'id')
        ->where('expiry_date', '>', date('d/m/Y', strtotime('today')))->orderBy('expiry_date', 'DESC')->limit(1);
    }

public function latestBooking(){
    return $this->hasOne('App\Models\Bookings', 'room_id', 'id')
    ->orderBy('expiry_date', 'DESC')->limit(1);
}

然后,回答您的问题:

if ($request->has('filters.vacant_from')) {
        $rooms = $rooms->whereHas('latestBooking', function ($query) use ($request) {
            $query->where('expiry_date', '<', Carbon::createFromFormat('d/m/Y',$request->input('filters.vacant_from'))->format('Y-m-d'));
        })->orWhereDoesntHave('latestBooking');
    }

过滤器查询的作用是:它获取所有expiry_date少于vacant_from日期的最新预订...而orWhereDoesntHave获取所有从未预订的客房

答案 1 :(得分:2)

预订关系应该是这样,

public function latestBooking(){
    return $this->hasMany('App\Models\Bookings')->orderBy('expiry_date', 'DESC');
}

因为这是一对多的关系。 laravel relationship

您可以这样编写过滤器,

  if ($request->has('filters.vacant_from')) {
        $rooms = $rooms->whereHas('latestBooking', function ($query) use ($request) {
            $query->whereDate('expiry_date', '<', Carbon::createFromFormat('d/m/Y',$request->input('filters.vacant_from'))->format('Y-m-d'));
        });
    }

您可以使用whereDate在laravel中运行日期查询。希望这会有所帮助

答案 2 :(得分:1)

假设您在hasManyRooms模型之间有Bookings关系,名称为bookings

$rooms = Rooms::whereHas('bookings', function ($query) use ($request) {
            $query->whereDate('expiry_date', '<', Carbon::createFromFormat('d/m/Y',$request->input('filters.vacant_from'))->format('Y-m-d'));
        })->orWhereDoesntHave('bookings')->get();