Laravel éloquent et relationnel
-
20-12-2019 - |
Question
J'ai un code:
$response = $this->posts
->where('author_id', '=', 1)
->with(array('postComments' => function($query) {
$query->where('comment_type', '=', 1);
}))
->orderBy('created_at', 'DESC')
->limit($itemno)
->get();
Et quand j'ai enregistré cette requête avec :
$queries = \DB::getQueryLog();
$last_query = end($queries);
\Log::info($last_query);
Dans le fichier journal, je vois ceci :
"select * from `post_comments` where `post_comments`.`post_id` in (?, ?, ?, ?) and `comment_type` <> ?"
Pourquoi le point d'interrogation pour comment_type dans la requête ?
Mise à jour n°1 :
J'ai remplacé le code actuel par le suivant et j'obtiens ce que je veux.Mais je ne suis pas sûr que ce soit OK.Il existe peut-être une solution bien meilleure et plus agréable.
$response = $this->posts
->where('author_id', '=', 1)
->join('post_comments', 'post_comments.post_id', '=', 'posts.id')
->where('comment_type', '=', 1)
->orderBy('created_at', 'DESC')
->limit($itemno)
->get();
La solution
Dans les coulisses, le AOP est utilisé et c'est ainsi que PDO
fait comme une requête préparée, par exemple vérifiez ceci :
$title = 'Laravel%';
$author = 'John%';
$sql = "SELECT * FROM books WHERE title like ? AND author like ? ";
$q = $conn->prepare($sql);
$q->execute(array($title,$author));
En exécution lors de l'exécution de la requête par execute()
le ?
les notes seront remplacées par la valeur transmise execute(array(...))
. Laravel/Eloquent
les usages PDO
et c'est un comportement normal PDO
(Objets de données PHP).Il existe une autre manière utilisée dans PDO
, qui est nommé parameter/placeholder
comme :totle
est utilisé à la place de ?
.En savoir plus à ce sujet dans le lien donné, c'est un autre sujet.Vérifiez également cette réponse.
Mise à jour: Au moment de l'exécution, le ?
les marques seront remplacées par la valeur que vous avez fournie, donc ?
sera remplacé par 1
.Aussi ceci query
est la requête relationnelle, la deuxième partie après le chargement de la première requête id
s du posts
tableau.Pour voir tous les journaux de requêtes, essayez plutôt ceci :
$queries = \DB::getQueryLog();
dd($queries);
Vous pouvez vérifier les deux dernières requêtes pour déboguer les requêtes pour l'appel suivant :
$response = $this->posts
->where('author_id', '=', 1)
->with(array('postComments' => function($query) {
$query->where('comment_type', '=', 1);
}))
->orderBy('created_at', 'DESC')
->limit($itemno)
->get();
Mise à jour après clarification :
Vous pouvez utiliser quelque chose comme ceci si vous avez une relation de configuration dans votre Posts
modèle:
// $this->posts->with(...) is similar to Posts::with(...)
// if you are calling it directly without repository class
$this->posts->with(array('comments' =. function($q) {
$q->where('comment_type', 1);
}))
->orderBy('created_at', 'DESC')->limit($itemno)->get();
Pour que cela fonctionne, vous devez déclarer la relation dans votre Posts
(Essayez d'utiliser un nom au singulier Post
si possible) modèle :
public function comments()
{
return $this->hasmany('Comment');
}
Ton Comment
le modèle devrait ressembler à ceci :
class Comment extends Eloquent {
protected $table = 'post_comments';
}