我正在开发一个简单的任务应用程序。我想急切地加载每个项目花费的总时间。我有两个表:
Table: task_project
id, client_id, name, description
Table: task_entries
id, task_project_id, start_time, end_time
表之间的关系是通过 task_project.id = task_entries.task_project_id
建立的。
对于表 task_project
中的每个项目,我们以 task_entries
为单位跟踪每个任务的时间。我创建了一个名为elapsed
的方法来处理这个问题。
所以在我的模型TaskProject
中,我有一个tasks
和elapsed
的关系:
public function tasks()
{
return $this->hasMany(TaskEntry::class, 'task_project_id');
}
public function elapsed()
{
return $this->hasOne(TaskEntry::class, 'task_project_id')
->selectRaw('time_format(SUM(timediff(task_end_time, task_start_time)), "%H:%m:%s") AS hours')
->groupBy('task_entries.task_project_id');
}
然后在我的控制器中,我按如下方式调用它:
$tasks = TaskProject::with('elapsed')->paginate(15);
但是elapsed
的关系是每个项目行的空值。
我希望最终能够通过以下方式在我的刀片模板中以 hh:mm:ss 的形式访问此值:
$task->elapsed->hours
任何帮助不胜感激!
这是一个
有趣的方法。我以前遇到过如何从 Eloquent 获取聚合列表的问题。这是我能想到的最好的。
class TaskEntry
{
public static function addElapsedTo($tasks)
{
$ids = $tasks->pluck('id');
$placeholders = trim(str_repeat('?,', count($ids)), ',');
$times = DB::select('
SELECT
task_project_id,
TIME_FORMAT(
SUM(TIMEDIFF(task_end_time, task_start_time)),
"%H:%m:%s"
) AS hours
FROM task_entries
WHERE task_project_id IN ('.$placeholders.')
GROUP BY task_project_id
', $ids);
$times = collect($times)->groupBy('task_project_id');
foreach ($tasks as $task)
{
$task->setAttribute('elapsed', $times[$task->task_project_id]['hours']);
}
return $tasks;
}
}
然后你可以像这样使用它。
$tasks = TaskProject::paginate(15);
$tasks = TaskEntry::addElapsedTo($tasks);
$task->elapsed
包含已用小时数值。
这样,您可以执行两个数据库查询,而不是一个。但是,您仍然避免对每个结果执行查询。
像这样的方法对我来说效果很好。虽然感觉有点笨拙。我很想找到更好的方法。