【问题标题】:Order by count in many to many polymorphic relation in LaravelLaravel中多对多多态关系中的按计数排序
【发布时间】:2019-01-22 07:29:21
【问题描述】:
【问题讨论】:
标签:
laravel
laravel-5
eloquent
【解决方案1】:
我建议直接调用你已经做过的电话,即Tag::withCount(['video', 'post'])->get(),并将其添加到你的标签模型中:
// 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。
如果您真的关心速度,则必须手动创建查询并在其中进行添加。
【解决方案2】:
所以经过更多搜索后,我发现仅在一个查询中无法做到这一点,因为在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。希望它可以帮助其他人。