2017-02-08 7 views
0

У меня есть простая структура, в которой сообщение имеет много голосов. Голос имеет свойство «значение», которое является либо 1, либо -1Лучший способ вернуть агрегирование сумм свойств отношений

При чтении всех сообщений мне хотелось бы выбрать эту сумму для каждого сообщения в обычное свойство на уровне сообщения. В настоящее время я сделать это

$posts = Post::where('published_at', '<=', $date) 
     ->orderBy('published_at', 'desc') 
     ->simplePaginate(20); 

    $posts->each(function($post) { 
     $post->overallRating = $post->getRating(); 
    }); 

Это полностью рабочий, но я думаю, что это не так уж хорошо, чтобы сделать как 20 запросов к базе данных, чтобы прочитать рейтинги. Есть ли способ упростить это при фактической выборке сообщений?

public function getRating() 
{ 
    return $this->votes->sum('value'); 
} 
+0

Не могли бы вы показать метод 'getRating()'? –

+0

добавил (а) в сообщение –

+0

Какую версию Laravel вы используете? –

ответ

2

Если вы хотите сохранить голоса включены в в результатах постраничной тогда я предложил бы добавить with('votes') так они, по крайней мере хотят загружены т.е.

$posts = Post::with('votes') 
    ->where('published_at', '<=', $date) 
    ->orderBy('published_at', 'desc') 
    ->simplePaginate(20); 

Однако, если вы не хотите/не беспокоитесь о наличии голосов, и вы просто хотите, чтобы Оценки каждого пост можно добавить следующие возможности для вашей Post модели:

public function scopeWithRating(Builder $query) 
{ 
    if (is_null($query->getQuery()->columns)) { 
     $query->select([$query->getQuery()->from . '.*']); 
    } 

    $query->selectSub(
     $this->votes()->getRelationExistenceQuery(
      $this->votes()->getRelated()->newQuery(), $query, new Expression('sum(value)') 
     )->toBase(), 
     'rating' 
    ); 
} 

Тогда:

$posts = Post::withRating() 
    ->where('published_at', '<=', $date) 
    ->orderBy('published_at', 'desc') 
    ->simplePaginate(20); 

Надеется, что это помогает!

+0

благодарит! Отлично. На данный момент мне действительно не нужны голоса! –

+0

@FrankProvost Рад, что я мог бы помочь! –

0

Попробуйте это:

$posts = Post::where('published_at', '<=', $date) 
     ->orderBy('published_at', 'desc') 
     ->with(['votes' => function($query) { 
      $query->sum('value'); 
     }])->simplePaginate(20); 
+0

Это не возвращает сумму - она ​​просто возвращает сообщения со всеми их голосами –

 Смежные вопросы

  • Нет связанных вопросов^_^