Laravel 5 Laravel雄辩,在单个查询中选择具有关系的模型

Laravel 5 Laravel雄辩,在单个查询中选择具有关系的模型,laravel-5,eloquent,Laravel 5,Eloquent,假设我们对车型和驾驶员有多对多关系: class Car extends Model {...} class Connection extends Model { public function car() { return $this->belongsTo('app\Car'); } public function driver() { return $this->belongsTo('App\Driver

假设我们对车型和驾驶员有多对多关系:

class Car extends Model {...}

class Connection extends Model
{
    public function car()
    {
        return $this->belongsTo('app\Car');
    }

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

class Driver extends Model {...}
现在我想查询一下约翰可以驾驶的汽车。对于QueryBuilder,这非常简单:

 $query = DB::table('cars')
        ->join('connections', 'cars.id', '=', 'connections.car_id')
        ->join('drivers', 'connection.driver_id', '=', 'drivers.id')
        ->where('drivers.name', 'like', 'John')->select('cars.*')->get();
这将生成一个SQL查询,这或多或少是我所期望的

应用程序的其余部分使用Eloquent进行数据库查询,因此我想用Eloquent重写这一部分。我对它进行了多次尝试,但我无法生成一个包含普通联接(而不是子查询)的查询。可能吗

您可以使用belongToMany关系并删除您的连接模型

将您的模型更改为:

class Car extends Model
{
    public function drivers()
    {
        return $this->belongsToMany(Driver::class, 'connection');
    }
}

class Driver extends Model
{
    public function cars()
    {
        return $this->belongsToMany(Car::class, 'connection');
    }
}
并通过以下方式查询驾驶员的车辆:

$drivers = Driver::with('cars')
    ->where('name', 'like', 'John')
    ->get();

foreach ($drivers as $driver) {
    $cars = $driver->cars;
}

另一个小优化是遵循Laravel关于表命名的约定,并将连接表调用为car_driver,这样您就可以从belongstomy方法中删除第二个参数。

您可以使用where has elought函数来获取可以由John驾驶的汽车

$cars = Car::whereHas('drivers',function($query) use ($driver_name){
       $query->where('name','like','%'.$driver_name.'%');
})->get();

对于模型,您可以使用@Idob写在其答案中的模型。

我不能使用belongstomy,因为我的连接模型比上面示例中的模型稍微复杂一些。我检查了你的代码,它工作正常,但效率低下;Laravel展示了执行的两个查询。另外,在您的示例中,您首先调用,但如果我使用所有名为John的驱动程序,则生成的查询将变得更加低效,因为id位于…我已更新为查询以支持多个驱动程序,请检查它。对于你提到的效率低下——没错,这是两个问题,而不是一个问题。一般来说,ORM的效率不如编写自己的查询,但您得到的好处是值得的。所以,除非这是一个每天点击数千万次的页面,否则我会坚持使用ORM&Elotent。我明白了,因此得出结论:实际上没有办法有一个且只有一个查询。是吗?因为每个雄辩的模型都充当一个查询生成器,所以您可以调用Car类而不是DB,并删除表“cars”,但它是同一个查询生成器,所以这并不重要。