首页 > 解决方案 > 雄辩的查询未按预期构建

问题描述

我有三个模型:

出租.php

  class Rental extends Model
    {
    use SoftDeletes;

    public function rentalItem()
    {
        return $this->hasMany('App\Models\RentalItem');
    }
}

RentalItem.php

class RentalItem extends Model
{
    public function rentalAsset()
    {
        return $this->belongsTo('App\Models\RentalAsset');
    }

    public function rental()
    {
        return $this->belongsTo('App\Models\Rental');
    }
}

和 RentalAsset.php

class RentalAsset extends Model
{    
    public function rentalItem()
    {
        return $this->hasMany('App\Models\RentalItem');
    }
}

一个 Rental 可以有多个 RentalItems 属于 RentalAsset。RentalAsset 是每个 RentalItem 的产品卡,因此一个 RentalItem 可以有一个 RentalAsset。

在创建 RentalItem 时,首先需要检查它是否在日期间隔内可用。这通过检查 date_from 和 date_two 之间是否是某个具有与 RentalAsset 相关的 RentalItem 的 Rental 来完成。

我想要一个查询,它将返回所有与在这些日期内与 Rental 相关的 RentalItem 不相关的 RentalAssets。

不幸的是,这不能正常工作:

$freeAssets = RentalAsset::where('rental_asset_category_id', '=', $request->rental_asset_category_id)
    ->whereDoesntHave('rentalItem.rental', function($query) use($date_from, $date_to)
        {
            $query->where('date_from', '<=', $date_to);
            $query->where('date_to', '>=', $date_from);
        })
    ->get();

非常感谢您的帮助!非常感谢。

更新:使用 Laravel 5.6

更新 2:我通过提供的 eloquent 查询输出生成的选择:

select * from `rental_assets` where `rental_asset_category_id` = ? and exists 
(select * from `rental_items` where `rental_assets`.`id` = `rental_items`.`rental_asset_id` and not exists 
    (select * from `rentals` where `rental_items`.`rental_id` = `rentals`.`id` 
        and `date_from` <= ? and `date_to` >= ? and `rentals`.`deleted_at` is null)) 
and `rental_assets`.`deleted_at` is null

这个选择返回我需要的:

select * from `rental_assets` where `rental_asset_category_id` = 2 
and not exists (
    select * from `rental_items` where `rental_assets`.`id` = `rental_items`.`rental_asset_id` and exists 
        (select * from `rentals` where `rental_items`.`rental_id` = `rentals`.`id` 
            and `date_from` <= '2018-12-12' and `date_to` >= '2018-01-01' and `rentals`.`deleted_at` is null)) 
and `rental_assets`.`deleted_at` is null;

什么是正确的雄辩查询?我宁愿那样做原始查询。谢谢。

标签: sqllaravellaravel-5eloquentlaravel-5.6

解决方案


这可能是您在这里需要的:

$freeAssets = RentalAsset::where('rental_asset_category_id', $request->rental_asset_category_id)
        ->whereDoesntHave('rentalItem', function($query) use ($date_from, $date_to) {
            $query->whereHas('rental', function($query) use ($date_from, $date_to) {
                $query->where('date_from', '<=', $date_to);
                $query->where('date_to', '>=', $date_from);
            });  
         })->get();

推荐阅读