让我们以文档中的示例为例:https://laravel.com/docs/5.7/eloquent-relationships#many-to-many-polymorphic-relations很容易获得所有posts
且其tags
计数为Post::withCount('tags')->get()
。
但是如何获取所有tags
及其使用计数?按最常用/最不常用的顺序排序。
如果我做Tag::withCount(['video', 'post'])->get()
,我将有2个属性videos_count
和posts_count
。就我而言,我想要一个唯一的taggables_count
,它将是两者之和。在理想情况下,通过添加子选择查询数据透视表。
答案 0 :(得分:0)
我建议您简单地进行您已经进行的通话,即Tag::withCount(['video', 'post'])->get()
,并将其添加到您的Tag模型中:
// Tag.php
class Tag
{
...
// Create an attribute that can be called using 'taggables_count'
public function getTaggablesCountAttribute()
{
return $this->videos_count + $this->posts_count;
}
...
}
,然后在循环中(或使用集合中的项目):
@foreach($tags as $tag)
{{ $tag->taggables_count }}
@endforeach
此设置要求您使用withCount['video', 'post']
获取标签。否则,您可能会得到0
来换取$tag->taggables_count
。
如果您真的担心速度,则必须手动创建查询并在其中进行添加。
答案 1 :(得分:0)
因此,在进行更多搜索之后,我发现仅凭一个查询就无法执行此操作,原因是在mysql
中我们无法对子子集结果进行选择。因此,执行Tag::withCount(['videos', 'posts'])
并尝试对查询videos_count
和posts_count
求和将不起作用。我最好的方法是创建一个在数据透视表中读取结果的范围:
public function scopeWithTaggablesCount($query) {
if (is_null($query->getQuery()->columns)) {
$query->select($query->getQuery()->from . '.*');
}
$query->selectSub(function ($query) {
$query->selectRaw('count(*)')
->from('taggables')
->whereColumn('taggables.tag_id', 'tags.id');
}, 'taggables_count');
return $query;
}
要使用它:
$tags = Tag::withTaggablesCount()->orderBy('name', 'ASC')->get();
因此,现在每个标签都有一个taggables_count
,它可以用于order by
。希望它可以帮助别人。