Получить среднее значение из полиморфного отношения

#laravel #eloquent

#ларавель #красноречивый

Вопрос:

Я одновременно пытаюсь получить количество отзывов и средние оценки отзывов.

У меня есть таблицы:

Таблицы:

  • ID
  • …..

Стулья:

  • ID
  • …..

Отзывы:

  • ID
  • Оценка
  • проверяемый идентификатор
  • проверяемой_тип
 class Review extends Model {
    public function reviewable() {
        return $this->morphTo();
    }

}

class Tables extends Model {
    public function reviews() {
        return $this->morphMany('AppReview', 'reviewable');
    }

    public function avg_rating() {
        return $this->reviews()
            ->selectRaw('avg(rating) as avgRating, review_id')
            ->groupBy('review_id');
    }

}
 

Я уже пробовал:

 Table::with(['avg_rating'])->withCount('reviews')->where(function($q) use ($regex_terms, $terms){
   $q->where('name', 'REGEXP', $regex_terms);
})->get();
 

Но получение «Неизвестного столбца ‘review_id’ в ‘списке полей'» или попытка его использования с вариантами «hasmany» дали только пустой массив или массив с отзывами. Просто интересно, каков наилучший способ добиться этого, или мне придется перебирать обзоры и вычислять вручную или второй необработанный запрос

У меня есть это, но я не уверен, является ли это эффективной или лучшей практикой в Eloquent:

 $tables->each(function ($table) {
    $table->review_average = DB::table('reviews')
    ->select(DB::raw("ROUND( avg(rating), 2) as avg"))
    ->where("reviewable_id", "=", $table->id)->first()->avg;
});
 

Комментарии:

1. laravel.com/docs/8.x/queries#aggregates

2. вы пробовали withAvg метод?

3. @ManojKiran Спасибо! Это поставило меня на правильный путь. По-видимому, я использовал Lumen на основе фреймворка Laravel 6, поэтому он выдавал ошибку «метод не найден», когда я пробовал это раньше. Но после поиска этого метода я увидел, что это была функция Laravel более высокой версии. Итак, обновление до Laravel / Lumen 8 решило проблему.

Ответ №1:

По-видимому, я использовал Lumen на основе фреймворка Laravel 6, поэтому он выдавал ошибку «метод не найден», когда я пробовал «withAvg» раньше. Но после поиска этого метода я увидел, что для него требуется более высокая версия Laravel. Итак, обновление до Laravel / Lumen 8 позволило мне использовать функцию «withAvg».

Итак, теперь мой оператор построения запросов выглядит следующим образом:

 Table::with(['avg_rating'])->withCount('reviews')->withAvg("reviews", "rating")->where(function($q) use ($regex_terms, $terms){
   $q->where('name', 'REGEXP', $regex_terms);
})->get();