【发布时间】:2015-08-26 15:18:29
【问题描述】:
自从我开始使用 Laravel 以来,我就遇到了这个问题。当我想拥有一个没有特定嵌套关系的实体时,在我的一生和无数小时中,我无法通过 eloquent has() 方法获得它。我通常通过 Fluent 和左连接来做到这一点。
假设有三个模型,其中一个轴 (user_persona) 只携带相关模型的 ID;
示例
| User | | Persona | | Category |
----------- -------------- ---------------
| user_id | -M-M- | persona_id | -O-M- | category_id |
----------- -------------- | persona_id |
---------------
关系
用户
function personas()
{
return $this->belongsToMany('Persona', 'user_persona', 'user_id', 'persona_id');
}
角色
function categories()
{
return $this->hasMany('Category', 'persona_id');
}
问题
现在可以通过以下方式获得具有特定类别角色的用户:
User::has('personas.categories', '>=', 1, 'and', function ($q) use ($cid) {
$q->where('category.category_id', '=', $cid)
})->first();
但我无法获取与同一类别没有这种关系的所有其他用户;
User::has('personas.categories', '=', 0, 'and', function ($q) use ($cid) {
$q->where('category.category_id', '=', $cid)
})->get();
Eloquent 将返回用户,包括所有与角色有任何其他关系的用户。那些匹配排除关系但也有另一个不匹配的关系的用户也将被包括在内。只有那些使其所有相关角色都符合条件的才会被过滤。
Fluent 中的预期相似查询
总而言之,我希望它返回与以下查询相同的结果:
SELECT
user.*
FROM
user u
LEFT JOIN user_persona up ON u.user_id = up.user_id AND up.persona_id IN
(SELECT persona_id FROM persona_category WHERE category_id = ?)
WHERE
up.persona_id IS NULL;
当前 Eloquent 生成的查询
SELECT
COUNT(*)
FROM
`user`
WHERE
(
SELECT
count(*)
FROM
`persona`
INNER JOIN `user_persona` ON `persona`.`persona_id` = `user_persona`.`persona_id`
WHERE
`user_persona`.`user_id` = `user`.`user_id`
AND (
SELECT
count(*)
FROM
`persona_category`
WHERE
`persona_category`.`persona_id` = `persona`.`persona_id`
AND `persona_category`.`category_id` = ?
) = ?
) >= ?
【问题讨论】: