Salut à tous,

Je rencontre un petit souci avec mon eager loading (Laravel 5.2) :
J'ai un scope qui me permet de récupérer mes derniers articles :

public function scopeLastPosts($query, $limit = 6) {
      $query
        ->with(['Category' => function ($query) {
          $query->select('id', 'name');
        }])
        ->select('*')
        ->where('is_published', true)
        ->orderBy('created_at', 'desc')
        ->limit($limit);

      return $query;
    }

Mon model Post est relié au model Category via une relation de type belongsTo (jusque là tout va bien).
Le eager loading est bien pris en compte, j'ai deux queries, une pour les posts l'autre pour les catégories.

select * from `posts` where `is_published` = '1' order by `created_at` desc
select `id`, `name` from `categories` where `categories`.`id` in ('20')

Seulement voilà, juste après j'ai systématiquement la query ci-dessous, qui est exécuté autant de fois que je récupère d'articles (ici 3) :

select * from `categories` where `categories`.`id` = '20' limit 1
select * from `categories` where `categories`.`id` = '20' limit 1
select * from `categories` where `categories`.`id` = '20' limit 1

Ma question est simple : Pourquoi ??

9 réponses


AlexJM
Réponse acceptée

Ce que je voulais dire, c'est que si tu as une relation genre :

function category(){
    $this->belongsTo('...');//Peu importe la relation
}

Si tu fais pour l'eager loading :

$c = Class::with('Category')->get();

et après pour avoir la catégorie tu fais

$c->category;

Tu as fait le eager loading de Category et non de category donc il va relancer la requête ;)

salut, je sais pas si c'est ca mais attention; le with est case sensitive

betaWeb
Auteur

@AlexJM c'est-à-dire ? La méthode with() tu veux dire ? Je ne pense pas que ce soit ça puisqu'il le eager loading est bien appliqué :/

Peut-être que @AlxJM a raison. Essaye

public function scopeLastPosts($query, $limit = 6) {
      $query
        ->with(['category' => function ($query) {
          $query->select('id', 'name');
        }])
        ->select('*')
        ->where('is_published', true)
        ->orderBy('created_at', 'desc')
        ->limit($limit);

      return $query;
    }

Et montre nous également le code qui détermine la relation entre Post et Category.

betaWeb
Auteur

@sizo0 Il s'agit d'une relation belongsTo.

use 'App\Category';
/* ... */
public function category() {
      return $this->belongsTo('Category');
  }

Mais comme je l'ai précisé, l'eager loading est bien appliqué. Il y a juste des queries 'parasites' en plus et je n'arrive pas à déterminer d'où elles peuvent venir.

Je ne pense pas que le eager loading est appliqué parce que la query 'Select ... from categories ...' est répétée plusieurs fois.
Applique le changement que je t'ai dit dans le message précédent et dans la méthode category qui détermine la relation, précise bien le namespace de la classe Category.

public function category() {
  return $this->belongsTo(Category::class);
}

ou

public function category() {
  return $this->belongsTo('App\Category');
}
betaWeb
Auteur

@sizo0 Merci pour tes conseils, j'essaye ça ce soir (je suis au taf là ^^).

betaWeb
Auteur

@AlexJM Merci beaucoup, ta solution était la bonne :)
Merci également à @sizo0 pour tes conseils :)

Pas de problème ;)