我想得到这个非常简单、常见的
SELECT
语句的结果:
SELECT * FROM parent
JOIN child ON parent.id = child.parent_id
WHERE child.column = 1;
对于非 SQL 流利者,这将返回所有父行和子行的所有列,其中名为
column
的子列包含值 1。
使用下面的 Laravel 模型,正确的 Eloquent 方法是什么?
<?php
class TheParent extends Model {
public function child(): HasMany {
return $this->hasMany(Child::class);
}
}
class Child extends Model {
public function parent(): BelongsTo {
return $this->belongsTo(TheParent::class);
}
}
// Fails. Returns empty set.
$data = TheParent::getModel()
->child()
->where('column', 1)
->get(); // returns empty set
// Fails: Returns correct data FOR JUST ONE parent Model if and only if a
// child meets the conditions. But find() is not usable for my purpose.
$data = TheParent::find(1)
->child()
->where('column', 1)
->get();
// Fails: Only returns the parent data and cannot reference the child.
$data = TheParent::whereHas(
'child',
function ($query) {
$query->where('column', 1);
}
)->get();
您已接近上次尝试;您的回调会过滤返回的
Parent
实例,但不会过滤附加的 Child
实例。尝试这样的事情:
$data = TheParent::whereHas('child', fn($q) => $q->where('column', 1))
->with(['child' => fn($q) => $q->where('column', 1)])
->get();
必须对
whereHas
和 with
方法重复回调...
TheParent::with('child')
返回所有父母和所有孩子TheParent::with(['child' => 'some condition'])
返回所有带有一些孩子的父母TheParent::whereHas('child', 'some condition')
返回一些父母和所有孩子TheParent::whereHas('child', 'some condition')->with(['child' => 'some condition'])
返回一些父母和一些孩子。从 Laravel 9.0 开始,如果
with()
和 whereHas()
使用相同的过滤器,则可以通过调用 withWhereHas()
来简化代码:
$data = TheParent::withWhereHas('child', fn($q) => $q->where('column', 1))->get();