我想得到这个非常简单,常见的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'])
返回一些家长和一些孩子。