Laravel 5.1, Eloquent - Select catégories et compter nombre d'articles par catégorie

Avatar de l’utilisateur
Eléphant du PHP | 69 Messages

14 juil. 2016, 13:42

Bonjour,

Je fait appelle à aide SVP, car je voudrai un renseignement SVP. Avec Laravel 5.1, je souhaite récupérer ma liste des catégories, et de compter le nombre d'articles par catégories.
Je le fait avec Query builder, mais je souhaiterai savoir si c'est possible de le faire avec Eloquent.
J'ai ceci :

Deux models : un model Article et un model Categoryarticle

Et trois table :
_Une table 'articles' (contient mes articles)
_Une table 'categoriesarticle' (contient mes catégories que je peut relier à mes articles)
_Une table 'article_categoryarticle' (table pivot pour faire la relation Many To Many entre les deux tables précédentes)

Avec Query builder en code ça donne ceci (dans le model categoryarticle).

Code : Tout sélectionner

<?php /* Récupérer la liste des catégories, et nombre d'articles par catégorie @param int $status @param string $getQ @return array */ public function findAndCountNbArticlesByCategory($status, $getQ) { $article = new Article(); return DB::table(self::TABLE) ->select([self::TABLE.'.id', self::TABLE.'.name', self::TABLE.'.description', DB::raw('COUNT('.$article->table().'.id) as nb_articles')]) ->leftJoin(self::TABLE_INTERMEDIATE_JOINED_ARTICLES, self::TABLE.'.id', '=', self::TABLE_INTERMEDIATE_JOINED_ARTICLES.'.categoryarticle_id') ->leftJoin(Article::TABLE, Article::TABLE.'.id', '=', self::TABLE_INTERMEDIATE_JOINED_ARTICLES.'.article_id') ->where(Article::TABLE.'.status', $status) ->groupBy(self::TABLE.'.id', self::TABLE.'.name', self::TABLE.'.description') ->orderBy('id', 'DESC') ->get(); } }
J'aimerai arriver au meme résultat avec Eloquent

Car le problème avec Query builder, c'est que je ne peut pas travailler avec des objets de mon model. Par exemple, je ne peut pas utiliser des méthode "de logique" comme celle ci :

Code : Tout sélectionner

<?php /* @return bool - True si la catégorie a une description */ public function hasDescription() { return ($this->description != '' && $this->description != null); }
Car Query builder retorune seulement une requete SQL, contrairement à Eloquent qui lui retourne une collection d'objets du model graàce au résultat de la requete SQL.

Merci d'avance.

Mammouth du PHP | 985 Messages

01 août 2016, 14:01

Bonjour et mettre le result dans une collection, ne simplifierais pas ?

Code : Tout sélectionner

$data = collect(findAndCountNbArticlesByCategory($status, $getQ))
L'expérience est la somme de toutes nos erreurs.

Nestecha
Invité n'ayant pas de compte PHPfrance

17 sept. 2016, 12:16

Hello !

Commence déjà par changer le nom de tes tables. Il serait plus simple et réel d'utiliser 'articles', 'categories' et 'article_category' pour la table pivot.

Ensuite, tu devrais avoir une relation liant les 2 modèles, une relation belongsToMany() !

Une fois que tu as ceci, tu devrais pouvoir faire :
# Tes categories sous forme de collection !
$categories = Category::all();

# On peut utiliser les méthodes des collections Laravel :
$categoriesWithArticlesCount = $categories->map(function($category) {
    return ['category' => $category->name, 'articlesCount' => $category->articles()->count()];
});
Il est très important de garder les parenthèses apres articles car comme tu le dis, c'est ce qui construira une requête permettant de récupérer le count() sans récupérer les objets avant, c'est donc beaucoup moins lourd et plus performant !

Ceci te renverra un tableau avec les categories et le nombre d'articles associés à chacune d'entre elle. C'est évidemment en imaginant que tes categories ont un attribut 'name', mais tu vois l'idée ;)