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-х юзеров в сумме.

Вопрос: как можно реализировать такую задачу и не говнокодить?
  • Вопрос задан
  • 81 просмотр
Пригласить эксперта
Ответы на вопрос 4
@aleksejjjj
А если так:
public function posts()
{
    return $this->hasMany(Posts::class);
}

public function postsLimited()
{
    return $this->posts()->take(5);
}

public static function users()
{
     return self::whereIn('login', ['ivanov', 'petrov'])->with('postsLimited')->get();
}

Хотя мне вообще затея со статическим методом users не нравится.
Ответ написан
@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);
                           }]);
    }
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
22 февр. 2019, в 15:23
3000 руб./за проект
22 февр. 2019, в 15:12
300 руб./в час
22 февр. 2019, в 14:57
800 руб./в час