Laravel eloquente e relacionamento
-
20-12-2019 - |
Pergunta
Eu tenho um código:
$response = $this->posts
->where('author_id', '=', 1)
->with(array('postComments' => function($query) {
$query->where('comment_type', '=', 1);
}))
->orderBy('created_at', 'DESC')
->limit($itemno)
->get();
E quando registrei esta consulta com:
$queries = \DB::getQueryLog();
$last_query = end($queries);
\Log::info($last_query);
No arquivo de log, vejo o seguinte:
"select * from `post_comments` where `post_comments`.`post_id` in (?, ?, ?, ?) and `comment_type` <> ?"
Por que o ponto de interrogação para comment_type está na consulta?
Atualização nº 1:
Substituí o código atual pelo seguinte e consegui o que queria.Mas não tenho certeza se está tudo bem.Talvez exista uma solução muito melhor e mais agradável.
$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();
Solução
Nos bastidores o DOP está sendo usado e é assim que PDO
faz como uma consulta preparada, por exemplo, verifique isto:
$title = 'Laravel%';
$author = 'John%';
$sql = "SELECT * FROM books WHERE title like ? AND author like ? ";
$q = $conn->prepare($sql);
$q->execute(array($title,$author));
No tempo de execução durante a execução da consulta por execute()
o ?
marcas serão substituídas pelo valor passado execute(array(...))
. Laravel/Eloquent
usa PDO
e é um comportamento normal em PDO
(Objetos de dados PHP).Existe outra maneira que é usada em PDO
, que é nomeado parameter/placeholder
como :totle
é usado em vez de ?
.Leia mais sobre isso no link fornecido, é outro assunto.Verifique também esta resposta.
Atualizar: No tempo de execução o ?
as marcas serão substituídas pelo valor que você forneceu, então ?
será substituído por 1
.Também isso query
é a consulta relacional, a segunda parte após a primeira consulta ter carregado o id
é do posts
mesa.Para ver todos os logs de consulta, tente isto:
$queries = \DB::getQueryLog();
dd($queries);
Você pode verificar as duas últimas consultas para depurar as consultas da seguinte chamada:
$response = $this->posts
->where('author_id', '=', 1)
->with(array('postComments' => function($query) {
$query->where('comment_type', '=', 1);
}))
->orderBy('created_at', 'DESC')
->limit($itemno)
->get();
Atualização após esclarecimento:
Você pode usar algo assim se tiver uma relação de configuração em seu Posts
modelo:
// $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();
Para que funcione você precisa declarar o relacionamento em seu Posts
(Tente usar o nome singular Post
se possível) modelo:
public function comments()
{
return $this->hasmany('Comment');
}
Seu Comment
modelo deveria ser assim:
class Comment extends Eloquent {
protected $table = 'post_comments';
}