Mettre en place du eager loading
Posté : 24 juil. 2016, 02:23
Bonjour à tous,
Je me pose actuellement une question, je voudrais mettre en place du eager loading lorsque je fais des requêtes.
Dans mon cas j'ai une table Post, Tag, PostTag, vous vous doutez donc qu'un Post peut avoir plusieurs Tag.
Actuellement je récupère une Collection de Post et les tags associés comme ceci :
J'avoue que je ne sais pas trop comment faire ici.
J'ai un début de requête :
Comment procéderiez-vous ?
Pour plus d'infos vous pouvez consulter le dépôt github
Merci d'avance.
Je me pose actuellement une question, je voudrais mettre en place du eager loading lorsque je fais des requêtes.
Dans mon cas j'ai une table Post, Tag, PostTag, vous vous doutez donc qu'un Post peut avoir plusieurs Tag.
Actuellement je récupère une Collection de Post et les tags associés comme ceci :
SELECT
Post.idPost,
Post.name,
Post.slug,
Post.content,
GROUP_CONCAT(Tag.name) AS tags
FROM Post
LEFT JOIN PostTag
ON PostTag.idPost = Post.idPost
LEFT JOIN Tag
ON Tag.idTag = PostTag.idTag
GROUP BY Post.idPost
ORDER BY Post.idPost DESC;
Une fois la requête exécuté je parcours les résultats via un foreach et j'instancie dedans un objet PostViewModel et j'hydrate les données dedans, voici le cas concret :
<?php
namespace Blog\View\Model;
class PostViewModel
{
/** @var int */
public $id;
/** @var string */
public $name;
/** @var string */
public $slug;
/** @var string */
public $content;
/** @var array */
public $tags;
}
<?php
namespace Blog\Infrastructure\Finder;
use Blog\View\Model\PostViewModel;
use Illuminate\Support\Collection;
class PostFinder extends AbstractFinder
{
/**
* Retourne la liste des articles
*
* @param string $order
* @return Collection
*/
public function findAll($order = 'DESC')
{
$select = "
SELECT
Post.idPost,
Post.name,
Post.slug,
Post.content,
GROUP_CONCAT(Tag.name) AS tags
FROM Post
LEFT JOIN PostTag
ON PostTag.idPost = Post.idPost
LEFT JOIN Tag
ON Tag.idTag = PostTag.idTag
GROUP BY Post.idPost
ORDER BY Post.idPost {$order};
";
$statement = $this->db->createStatement($select);
$result = $statement->execute();
$posts = new Collection();
if ($result->isQueryResult() === false
|| $result->count() < 1
) {
return $posts;
}
foreach ($result as $row) {
$post = new PostViewModel();
$this->hydrate($row, $post);
$posts->push($post);
}
return $posts;
}
/**
* @param array $row
* @param PostViewModel $post
*/
private function hydrate(array $row, PostViewModel $post)
{
$post->id = (int)$row['idPost'];
$post->name = $row['name'];
$post->slug = $row['slug'];
$post->content = $row['content'];
$post->tags = $row['tags'] !== null
? (array)explode(',', $row['tags'])
: null;
}
}
Ce que je souhaiterais faire c'est une requête qui récupère tous les Post :
SELECT
Post.idPost,
Post.name,
Post.slug,
Post.content
FROM Post;
Et ensuite une autre qui ajouterait dans la collection des Posts l'attributs tags qui contiendrait mes tags sous forme d'objet TagViewModel avec les propriétés id et name.J'avoue que je ne sais pas trop comment faire ici.
J'ai un début de requête :
SELECT
Tag.idTag,
Tag.name,
PostTag.idPost
FROM Tag
LEFT JOIN PostTag
ON PostTag.idTag = Tag.idTag
WHERE PostTag.idPost IN (:ids)
:ids est récupéré quand je parcours ma collection, je pousse les ids dans un tableau.Comment procéderiez-vous ?
Pour plus d'infos vous pouvez consulter le dépôt github
Merci d'avance.