Метод withAvg
Метод withAvg применяется к запросу Eloquent для загрузки
среднего значения указанного столбца из связанных моделей.
Первый параметр - имя связи, второй - имя столбца для вычисления
среднего, третий (необязательный) - алиас для результата.
Если алиас не указан, используется имя связи и имя столбца,
разделённые через '_' с префиксом 'avg_'.
Результат доступен как атрибут модели.
Синтаксис
<?php
Model::withAvg($relation, $column, $alias)->get();
?>
Пример
Давайте получим список постов и для каждого загрузим средний рейтинг всех комментариев к этому посту:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
}
?>
<?php
namespace AppHttpControllers;
use AppModelsPost;
class PostController extends Controller
{
public function index()
{
$posts = Post::withAvg('comments', 'rating')->get();
foreach ($posts as $post) {
echo "Post: " . $post->title . ", Avg rating: " . $post->comments_avg_rating;
}
}
}
?>
Результат выполнения кода:
"Post: First post, Avg rating: 4.5"
"Post: Second post, Avg rating: 3.2"
"Post: Third post, Avg rating: 5"
Обратите внимание, что атрибут для доступа к результату
получается как 'comments_avg_rating', где
'comments' - имя связи, 'rating' - имя столбца.
Пример с алиасом
Давайте переименуем результирующее поле в 'avg_rating'
для более удобного доступа:
<?php
namespace AppHttpControllers;
use AppModelsPost;
class PostController extends Controller
{
public function index()
{
$posts = Post::withAvg('comments', 'rating', 'avg_rating')->get();
foreach ($posts as $post) {
echo "Post: " . $post->title . ", Avg rating: " . $post->avg_rating;
}
}
}
?>
Результат выполнения кода:
"Post: First post, Avg rating: 4.5"
"Post: Second post, Avg rating: 3.2"
"Post: Third post, Avg rating: 5"
Пример с фильтрацией связанных моделей
Давайте вычислим средний рейтинг только опубликованных
комментариев с помощью метода whereHas:
<?php
namespace AppHttpControllers;
use AppModelsPost;
class PostController extends Controller
{
public function index()
{
$posts = Post::withAvg('comments', 'rating')
->whereHas('comments', function ($query) {
$query->where('status', 'published');
})
->get();
foreach ($posts as $post) {
echo "Post: " . $post->title . ", Avg published rating: " . $post->comments_avg_rating;
}
}
}
?>
Результат выполнения кода:
"Post: First post, Avg published rating: 4.5"
"Post: Second post, Avg published rating: 5"