我正在尝试使用 Laravel hasOne(Model::class)->ofMany('relationship')
,但我还想另外过滤考虑的结果。
我的问题更详细一些:
我在所见即所得风格的创作工具中使用了这两个简化的表格:
文件:
id (PK),...
文件修订表:
id (PK),document_id (FK),revision_id,is_autosave,...
在修订表中,该组合document_id, revision_id, is_autosave
是唯一的,这意味着文档的自动保存和手动保存的修订可以具有相同的 revision_id。
我尝试使用以下代码将最新的手动保存的修订与文档模型相关联:
public function mainRevision() {
return $this->hasOne(DocumentRevision::class)
->where('autosave', false)
->ofMany('revision_id', 'max');
}
我可以将上面的内容称为例如Documents::with('mainRevision')->where(...)->get()
。目的是立即加载最新的手动修订版,并且仅加载所有匹配文档行的最新手动修订版。
然而,这会生成以下查询:
select
`document_revisions`.*
from
`document_revisions` inner join (
select
max(`document_revisions`.`id`) as `id_aggregate`,
min(`document_revisions`.`revision_id`) as `revision_id_aggregate`,
`document_revisions`.`document_id`
from
`document_revisions`
inner join (
select max(`document_revisions`.`revision_id`) as `revision_id_aggregate`,`document_revisions`.`document_id`
from `document_revisions`
where `document_revisions`.`document_id` in (`<list of matched ids from the 1st query>`)
group by
`document_revisions`.`document_id`
) as `mainVersion`
on `mainVersion`.`revision_id_aggregate` = `document_revisions`.`revision_id` and `mainVersion`.`document_id` = `document_revisions`.`document_id`
group by `document_revisions`.`document_id`) as `mainVersion`
on `mainVersion`.`id_aggregate` = `document_revisions`.`id`
and `mainVersion`.`revision_id_aggregate` = `document_revisions`.`revision_id`
and `mainVersion`.`document_id` = `document_revisions`.`document_id`
where
`autosave` = 0
虽然我可以看到这里的意图,但存在一个问题,即 是where autosave=0
添加到连接表之外的。这会导致这样的情况:如果最新的 revision_id 恰好只对应于自动保存,则不会拾取它。
理想情况下,我希望查询如下:
select
`document_revisions`.*
from
`document_revisions` inner join (
select
max(`document_revisions`.`id`) as `id_aggregate`,
min(`document_revisions`.`revision_id`) as `revision_id_aggregate`,
`document_revisions`.`document_id`
from
`document_revisions`
inner join (
select max(`document_revisions`.`revision_id`) as `revision_id_aggregate`,`document_revisions`.`document_id`
from `document_revisions`
where `autosave` = 0 --<<----------- change here
and `document_revisions`.`document_id` in (`<list of matched ids from the 1st query>`)
group by
`document_revisions`.`document_id`
) as `mainVersion`
on `mainVersion`.`revision_id_aggregate` = `document_revisions`.`revision_id` and `mainVersion`.`document_id` = `document_revisions`.`document_id`
group by `document_revisions`.`document_id`) as `mainVersion`
on `mainVersion`.`id_aggregate` = `document_revisions`.`id`
and `mainVersion`.`revision_id_aggregate` = `document_revisions`.`revision_id`
and `mainVersion`.`document_id` = `document_revisions`.`document_id`
有谁知道这是否可能?
请尝试以下操作,并
autosave = 0
在子查询中应用确定最新修订版本的条件。这是修改后的代码根据文档
ofMany()
,您可以通过传递闭包作为第二个参数来向查询添加条件。这还需要使用数组表示法在第一个参数中传递聚合列。下面的例子:不相关,但 Laravel 还有另一种定义您可能喜欢的“众多之一”的方法
hasMany()
,即将现有关系转换为hasOne()
. 这和你所拥有的没有什么区别,只是风格的偏好。假设您将hasMany()
关系定义为documentRevisions()
,您可以调用其one()
方法将其转换为hasOne()
关系: