我有一个项目,该项目可以有附加文件。项目和文档都是模型/表格。
简化的示例文档表:
-----------------------------------
| ID | filename | version |
-----------------------------------
| 1 | list.docx | 1 |
| 2 | list.docx | 2 |
| 3 | file.xls | 1 |
-----------------------------------
我希望有一些简单的版本控制,以便用户可以“替换”文档,新表行将复制ID和版本以外的所有先前条目值。
我的问题是我想使用一种关系来提取所有最新文档。我目前在Project模型中使用这种怪物:
public function latest_documents()
{
return $this->hasMany(Document::class)
->where('version', \DB::raw('(SELECT max(d.version) from documents d where d.filename = documents.filename)'))
}
必须有更好的方法吗?我尝试仅将groupBy()和max()用于关系,但出现错误。
编辑:在DB :: raw解决方案之前尝试了'Laravel方法':
public function documents()
{
return $this->hasMany(Document::class)->groupBy('filename')->max('version');
}
错误:
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
答案 0 :(得分:1)
我的建议是基于文档表创建一个MySQL视图,该视图始终仅包含最新的文档文件,并仅与该视图建立关系。所以:
步骤1 /创建视图:
create view latest_documents as
select filename,
max(version) as version,
project_id as project_id,
any_value(id) as id
from documents
group by project_id, filename;
第2步/创建视图模型:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class LatestDocument extends Model
{
//
}
步骤3 /将关系添加到项目模型中:
public function latest_documents()
{
return $this->hasMany(LatestDocument::class);
}
我对此进行了测试,应该可以工作。
注意:我在第一步中使用any_value()
来防止出现根据only_full_group_by
的错误。因此,如果您禁用了此模式(我不推荐),则无需在id
周围使用此功能。