我用的是拉维,我有一个简单的任务,就是找到所有在过去x天内没有打扫过的房间。
我需要使用雄辩和急切的加载,结果应该只包括结果与儿童记录,例如,如果1号楼的所有房间已在'x'天内清理完毕,1号楼根本不应返回…
建筑
+----+---------------+
| id | building_name |
+----+---------------+
| 1 | Building 1 |
| 2 | Building 2 |
+----+---------------+
房间
+----+-----------+-------------+
| id | room_name | building_id |
+----+-----------+-------------+
| 1 | Room 1 | 1 |
| 2 | Room 2 | 1 |
| 3 | Room 3 | 2 |
+----+-----------+-------------+
维护日志
+----+-------------------+---------+---------------------+
| id | maintenance_value | room_id | created_at |
+----+-------------------+---------+---------------------+
| 1 | Cleaned | 1 | 2015-09-01 00:54:59 |
| 2 | Cleaned | 1 | 2015-09-06 01:55:59 |
| 3 | Cleaned | 2 | 2015-09-02 02:56:59 |
| 4 | Cleaned | 2 | 2015-09-07 03:57:59 |
| 5 | Cleaned | 3 | 2015-09-03 04:58:59 |
| 6 | Cleaned | 3 | 2015-09-08 05:59:59 |
+----+-------------------+---------+---------------------+
建筑模型
class Building extends Model
{
public function rooms() {
return $this->hasMany('App\Room');
}
}
房间模型
class Room extends Model
{
public function maintenancelog() {
return $this->hasMany('App\Maintenancelog');
}
public function needCleaning() {
return $this->hasMany('App\Maintenancelog')->whereRaw('id in (select id from (select id, max(created_at) as created_at from maintenancelog
group by id having created_at < DATE_SUB(NOW(), INTERVAL 10 DAY)) x')
}
}
维护日志模型
class Room extends Model
{
}
控制器
use App\Room;
$result = Room::has('needCleaning')->with('needCleaning')->get(); //this seems redundant?
虽然我可以得到房间和相应的维护日志记录,
控制器代码似乎冗余(都
has()
和with()
)引用相同的方法…我也不太确定如何从建筑开始,然后是房间等,这样我就拥有了所有(而且只有)相关的建筑->房间->维护日志,所有其他的都不包括在收藏中。
房间模型用whereraw看起来有点笨重??这个逻辑应该改为maintenancelog模型吗?查询也很笨拙
有没有更简单或更好的方法来做我想做的事?
最佳答案
试试这个
模型
Class Building extends Eloquent
{
public function Rooms()
{
return $this->hasMany('Room');
}
}
Class Room extends Eloquent
{
public function MaintenanceLogs()
{
return $this->hasMany('MaintenanceLog');
}
}
代码
//set number of days before
$no_days = 5;
//get the start date where room was not cleaned
$start_date = date('Y-m-d', strtotime('-'.$no_days.' days', strtotime(date('Y-m-d'))));
//start eager loading
$query = Building::with(
array
(
'Rooms' => function($qry)
{
$qry->with('MaintenanceLogs');
}
)
);
//get all rooms that has
$query->whereHas('Rooms', function($qry) use ($start_date)
{
//exclude room that has maintenance log within this period date
$qry->whereDoesntHave('MaintenanceLogs', function($q) use ($start_date)
{
$q->where('created_at', '>=', $start_date);
});
});
$data = $query->get();
它将在5天内寻找没有维修记录的房间
但我不知道如何做嵌套作用域