我最近开始使用Laravel进行开发,我的第一个项目是车辆预订应用程序.
我似乎做得很好,但我仍然试图用Eloquent显示当前的预订.
该系统的工作原理是将车辆添加到车辆表中,将员工添加到员工表中.使用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 |
+----+-------------+------------+-----------+---------------------+---------+---------+
这些表具有扩展Eloquent的Vehicle和Employee模型.这些方法调用belongsToMany.
我想要做的是获得车辆收集并急切地将员工加载到它上面.这样我就可以显示当前已预订的车辆,以及目前已将其预订的车辆.
例如:
$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 |
+----+-------------+------------+-----------+---------------------+---------+---------+
这给了我每辆车预订一排(这是在加入任何员工之前).
但是现在我真的被卡住了.我只是无法弄清楚如何使用也加入Employees的Eloquent编写等效查询. (它还需要只显示当前“OUT”的车辆,但我想这是微不足道的部分!)
我可以使用DB :: raw(‘…’)编写查询,并且不介意手动编写长SQL查询,但是我真的想要正确使用它,尝试使用Eloquent.
我注意到了whereIn方法,但它只接受一个列名的字符串而不是多列的数组,所以这是不行的. (除非我遗漏了某些东西,或者计划将来的Laravel版本?)
我从来不是一个真正的框架粉丝,并且需要一些令人信服的,而不是希望被击败,与Laravel一起.这让我感到很沮丧,因为我觉得不要乱用Eloquent会更快.如果我能让这个工作,那么我会更加接受它.
解决方法:
让我们说你
员工模型:
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(‘Ymd H:i:s’,(time() – 3 * 30 * 24 * 60 * 60))因为您对日志数据库的查询非常数据库引擎的工作量很大,通常情况下,过去3个月的数据可以保证性能安全.
并尝试分页,而不是得到一切.