2016-06-21 82 views
4

我最近开始使用Laravel进行开发,而我的第一个项目是一个车辆预订应用程序。Laravel雄辩多栏IN条款

我似乎做得很好,但我被卡住试图显示当前预订使用雄辩。

该系统的工作原理是将车辆添加到vehicles表中,并将员工添加到employees表中。与数据透视表的多对多关系使用employee_vehicle创建。

员工

+------------+-------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+------------+-------------+------+-----+---------+----------------+ 
| id   | int(10)  | NO | PRI | NULL | auto_increment | 
| first_name | varchar(50) | NO |  | NULL |    | 
| surname | varchar(50) | NO |  | NULL |    | 
+------------+-------------+------+-----+---------+----------------+ 

车辆

+--------------+-------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+--------------+-------------+------+-----+---------+----------------+ 
| id   | int(10)  | NO | PRI | NULL | auto_increment | 
| registration | varchar(10) | NO |  | NULL |    | 
| make   | varchar(50) | NO |  | NULL |    | 
| model  | varchar(50) | NO |  | NULL |    | 
+--------------+-------------+------+-----+---------+----------------+ 

employee_vehicle

+-------------+------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+-------------+------------+------+-----+---------+----------------+ 
| id   | int(10) | NO | PRI | NULL | auto_increment | 
| employee_id | int(10) | NO |  | NULL |    | 
| vehicle_id | int(10) | NO |  | NULL |    | 
| direction | varchar(3) | NO |  | NULL |    | 
| date_booked | datetime | NO |  | NULL |    | 
| damaged  | tinyint(1) | NO |  | NULL |    | 
| mileage  | int(10) | NO |  | NULL |    | 
+-------------+------------+------+-----+---------+----------------+ 

结果

+----+-------------+------------+-----------+---------------------+---------+---------+ 
| id | employee_id | vehicle_id | direction | date_booked   | damaged | mileage | 
+----+-------------+------------+-----------+---------------------+---------+---------+ 
| 1 |   1 |   1 | OUT  | 2016-06-13 09:08:08 |  0 | 2357 | 
| 2 |   1 |   1 | IN  | 2016-06-16 16:29:26 |  0 | 2401 | 
| 3 |   2 |   1 | OUT  | 2016-06-20 10:47:28 |  0 | 2470 | 
| 4 |   3 |   2 | OUT  | 2016-06-14 09:18:52 |  0 | 1403 | 
+----+-------------+------------+-----------+---------------------+---------+---------+ 

这些表有VehicleEmployee模型扩展侃侃而谈。这些方法有belongsToMany

我想要做的是获得Vehicle集合,并热切地加载员工。这样,我可以显示目前预订的车辆以及目前预订的车辆。

例如:

$vehicleBookings = Vehicle::with(['employees'])->get();

,我会解释,一个预订的工作方式......

基本上,车辆和雇员使用数据透视表连接在一起。该表还记录预订日期,预订方向(例如预订IN或OUT)以及有关其状况的附加数据等。

重要的是IN和OUT都有条目,以便在那里是预订前后车辆状况的审计日志。

我遇到的问题是能够从可用预订中获得车辆的最新状态,以确定它目前是否已预订或可供预订。这决定了车辆可以做什么。

一些研究,我想出了以下查询后:

SELECT * 
FROM `employee_vehicle` 
WHERE (`vehicle_id`, `date_booked`) IN (
    SELECT `vehicle_id`, MAX(`date_booked`) 
    FROM `employee_vehicle` 
    GROUP BY `vehicle_id` 
) 

(我甚至不知道这是可能使用多列与IN子句到现在为止,但它是伟大的!)。

这给了我:

+----+-------------+------------+-----------+---------------------+---------+---------+ 
| id | employee_id | vehicle_id | direction | date_booked   | damaged | mileage | 
+----+-------------+------------+-----------+---------------------+---------+---------+ 
| 3 |   2 |   1 | OUT  | 2016-06-20 10:47:28 |  0 | 2470 | 
| 4 |   3 |   2 | OUT  | 2016-06-14 09:18:52 |  0 | 1403 | 
+----+-------------+------------+-----------+---------------------+---------+---------+ 

这给了我每一个曾经被预订车辆一行(这是加入任何员工之前)。

但是现在我真的被卡住了。我只是无法弄清楚如何使用Eloquent来编写一个同样的查询,这个查询也加入了Employees。 (它也需要只显示车辆当前“OUT”,但我想这是微不足道的一部分!)

可以只写使用DB::raw('...')查询,并没有手动介意写长的SQL查询,但我真的想给它一个正确的,尝试使用雄辩。

我注意到whereIn方法,但它只接受一个字符串作为一个列名而不是多列数组,所以这是一个不可行的方法。 (除非我错过了某些东西,或者它计划将来的Laravel版本?)

我从来没有真正的框架迷,并且需要一些令人信服的,不希望被打败,一直坚持与Laravel。这让我感到沮丧,因为我觉得只是为了不弄乱Eloquent会更快。如果我能得到这个工作,那么我会更加接受它。

+0

那么你在寻找员工和车辆在一起的employee_vehicle? – num8er

+0

简短的回答是肯定的。长答案是肯定的,但是我怎么写我发布的查询_but_使用Eloquent,_also_将所有东西都放在一起。我不知道我是否正确地解释自己。 – jren207

回答

0

比方说,你已经

员工型号:

class Employee extends Model { 
    protected $table = 'employees'; 
    public $timestamps = false; 
} 

和车型:

class Vehicle extends Model { 
    protected $table = 'employees'; 
    public $timestamps = false; 
} 

,你想通过vehicle_id分组最新日志。

所以,做一个模型:

class EmployeeVehicle extends Model { 
    protected $table = 'employee_vehicle'; 
    public $timestamps = false; 

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

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

和您请求DB将是这样的:

$EmployeeVehicles = EmployeeVehicle::with(['employee', 'vehicle']) 
            ->where('date_booked', '>', date('Y-m-d H:i:s', (time() - 3*30*24*60*60))) 
            ->groupBy('vehicle_id') 
            ->selectRaw('*, MAX(`date_booked`) AS `last_date_booked`') 
            ->paginate(50); 

附:我已经添加了where('date_booked', '>', date('Y-m-d H:i:s', (time() - 3*30*24*60*60)),因为您的查询数据库日志对于数据库引擎来说是非常繁重的工作,通常最好有过去3个月的数据来确保性能安全。

并尝试分页,而不是一切。

+0

啊,所以有可能将一个数据透视表制作成一个模型本身?这是标准/可接受的方式吗?我都很新:)。 – jren207

+0

当然可以!雄辩是强大的。如果你觉得有点不同(Eloquentish方式)(: – num8er

+0

)Bor me数据透视表是带有2个字段的表,没有id字段:employee_id,vehicle_id和数据透视表也可以用作模型,但请记住,您向我们显示的employee_vehicle是不是数据透视表,它更像是一个“日志”表(: – num8er