【发布时间】:2016-01-31 11:47:31
【问题描述】:
我正在运行这个查询:
Music::where('title', $title)->with(['artists.images'])->get();
结果,我有一个音乐列表
array:4 [▼
0 => Music {#276 ▶}
1 => Music {#275 ▶}
2 => Music {#274 ▶}
3 => Music {#273 ▶}
]
每首音乐都与艺术家有关(例如由 3 位艺术家演唱的音乐)
// Music #1
...
relations: array:1 [▼
"artists" => Collection {#269 ▼
items: array:3 [▶]
}
]
...
每个艺术家都与图像有关系(例如,一个艺术家有 7 个图像)
// Artist #1 of Music #1
...
relations: array:2 [▼
"pivot" => Pivot {#329 ▶}
"images" => Collection {#505 ▼
items: array:7 [▶]
}
]
...
一切正常。
但在我的视图文件中,当我这样做时(在 foreach 循环中)
@foreach($music->artists()->where('type', 'feature')->get() as $feature)
{{ $feature->name }}
@endforeach
它再次运行许多查询来实现这一点。 $music->artists 应该已经预先加载,因此不必再次运行查询。当我在上面运行dd() 时,它实际上包含了上面提到的关系。
如何在不再次运行这些查询的情况下简单地获取属性?
【问题讨论】:
-
您是否尝试在
with函数中添加“艺术家”,例如:->with(['artists','artists.images'])? -
还是一样的结果。问题是当我运行
dd()时,所有想要的关系都会显示出来。这意味着它已经成功地预先加载了对象。现在我想在不再次运行 SQL 查询的情况下获取这些属性。如我所见,调用$music->artists()->where(xxx)将再次运行查询。 -
当我运行
$music->artists时,没有执行其他查询。但是当我运行$music->artists()->where(xxx)时,会执行额外的查询。 -
在使用
artists()时创建一个新查询。另一种检查方法是在循环if($artist->type == 'feature')中使用正常的 php/blade 条件。或者,如果可能,您可以在执行查询之前应用 where 子句(在使用get()之前) -
啊,解决办法是
$artist->pivot->type。