vhuk1802
@vhuk1802

Как сделать выборку whereIn + with с лимитом по каждой записи?

Есть 2 таблицы:
users и posts

нужно сделать выборку whereIn в users

public static function users(){

return self::whereIn('login', ['ivanov', 'petrov' ])->get();

}


связь между users и posts работает через отношение

public function posts(){

return $this ->hasMany(Posts::class );

}


в конечном итоге построение таково:

public static function users(){

return self::whereIn('login', ['ivanov', 'petrov' ])->with(['posts' => function($query){

return $query -> take(5);

}])->get();

}

т.е. я хочу получить по 5 постов для каждого юзера, но orm мне возвращает 5 постов на 2-х юзеров в сумме.

Вопрос: как можно реализировать такую задачу и не говнокодить?
  • Вопрос задан
  • 94 просмотра
Пригласить эксперта
Ответы на вопрос 3
@jazzus
Можно попробовать со скопом в модели User

public function scopeOfLogins($query, $logins)
{
         $builder = $query->whereIn('login', $logins)
                         ->with(['posts' => function($q){
                                      $q->take(5);
                                     }]);
    return $builder;
}

в контроллере
$logins = ['ivanov', 'petrov'];
$users = User::ofLogins($login)->get();

или с форычем в юзере
public function scopeOfLogins($query, $logins)
{
    foreach ($logins as $login) {
         $builder = $query->where('login', $login)
                           ->with(['posts' => function($q){
                           $q->take(5);
                           }]);
    }
    return $builder;
}
Ответ написан
Комментировать
@vism
Вот как бывает, 2 решения и в обоих люди не знают как работат жадная загрузка... :)

Вот вам нормальное решение.
Чтоб взять последние 5 для каждой записи, у вас по любому надо делать отельный запрос на каждого Юзера. так БД работает, иначе очень сложный запрос получается типо такого.
$articles = `SELECT category, id, title FROM (
    SELECT c.name AS category, a.id, a.title, row_number() OVER (PARTITION BY categoryid ORDER BY a.sort DESC) AS row
    FROM articles a INNER JOIN categories c ON (a.categoryid=c.dboid)
    ORDER BY c.sort
) AS foo WHERE row <= 5;


Поэтому, сперва получаете юзеров, а потом проходите по ним циклом и получаете все что относится к постам
foreach ($users as $user) {
         user->load(['posts' => function($q){
                           $q->take(5);
                           }]);
    }
Ответ написан
Комментировать
@NubasLol
Использовать пакет

https://github.com/staudenmeir/eloquent-eager-limi...

По дефолту take в with не работает
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы