Порядок по количеству во многих полиморфных отношениях в Laravel - PullRequest
0 голосов
/ 13 января 2019

Давайте возьмем пример из документа: 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, который будет суммой двух. В идеальном мире, добавив подвыбор, запрашивающий сводную таблицу.

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Таким образом, после дополнительного поиска я обнаружил, что нет способа сделать это только в одном запросе из-за того, что в 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. Надеюсь, что это может помочь другим.

0 голосов
/ 13 января 2019

Я бы предложил просто сделать звонок, который вы уже сделали, то есть 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.

Если вы действительно беспокоитесь о скорости, вам придется создать запрос вручную и выполнить там добавление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...