Ir para conteúdo
Fórum Script Brasil
  • 0

A junção de três tabelas no Laravel Eloquent


Frank K Hosaka

Pergunta

Hoje eu fiz a minha primeira tentativa de ajuntar três tabelas, precisava traduzir em Eloquent a seguinte consulta SQL:

Select * from tbhistprod, tbpesssoa, tbprod where lcto=$lcto and tbhistprod.codprod = tbprod.codprod and tbhistprod.codp = tbpessoa.codp

Depois de criar um Model para cada tabela e relacionar todas elas no controller, a sintaxe ficou assim:

$produtos=tbprod::join('tbhistprod','tbhistprod.codprod','=','tbprod.codprod')
->join('tbpessoa','tbpessoa.codp','=','tbhistprod.codp')->where('lcto',$lcto)->get( );

Apesar de eu ter conseguido o resultado que eu queria, acredito que essa não é a forma mais adequada. Eu vi um tutorial em que o rapaz definia a relação das tabelas através do Model, usando o conceito de HasMany e BelongsTo. Esse vai ser o meu desafio dessa semana.

Editado por Frank K Hosaka
Link para o comentário
Compartilhar em outros sites

5 respostass a esta questão

Posts Recomendados

  • 0

O tutorial que fala da junção de três tabelas é esse daqui: php - How to join three table by laravel eloquent model - Stack Overflow

Aqui eu tenho duas enormes barreiras, a primeira é a língua inglesa e a segunda é a linguagem de programação. Eu não tenho a menor experiência nessas duas áreas, e assim só sobrou o método da tentativa e erro, ou o que os americanos chamam de improvisation.

Primeiro eu pego uma folha de papel e faço um esboço do que eu quero, usando a linguagem do tutorial:

tbhistprod 
codprod belongsTo tbprod
codp belongsTo tbpessoa

tbprod
codprod hasMany tbhistprod

tbpessoa
codp hasMany tbhistprod

goal:
$produtos=tbhisprod::with('tbprod','tbpessoa')->('lcto',$lcto)->get( ).

O próximo passo é usar o VS Code e colocar tudo isso dentro do projeto do Laravel, sem que o VS Code use aquelas minhocas vermelhas debaixo do código.


 

Link para o comentário
Compartilhar em outros sites

  • 0

Como sempre acontece, o método da tentativa e erro nunca dá certo.

Com o pouco que eu sei de inglês, eu abri um tópico em Laracasts. Se alguém vai entender o que eu escrevi, isso eu não sei:

Call to undefined relationship [tbprod] on model [App\Models\tbhistprod (laracasts.com)

Editado por Frank K Hosaka
Link para o comentário
Compartilhar em outros sites

  • 0

Em menos de cinco minutos, o fórum do Laracast respondeu a minha dúvida, afirmando que usei errado o comando with no controller, eu usei os nomes das tabelas, quando o correto é usar o nome das relações. Ele também sugeriu para eu usar o nome dos objetos sempre no plural, e eu comentei que não sou capaz nem capaz de saber o nome do objeto no singular. Aqui está a listagem final:

app>Http>Controllers>DiarioController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\tbconta;
use App\Models\tbdiario;
use App\Models\tbhistprod;
use App\Models\tbprod;
use App\Models\tbsupervariavel;
Use Auth;
class DiarioController extends Controller {
	public function detalhe(Request $request){
	$produtos=tbhistprod::with('relProdutos','relPessoas')->where('lcto',$lcto)->get();
    	dd(compact('produtos'));}}

app>Models>tbhistprod.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class tbhistprod extends Model{
    use HasFactory;
    protected $table="tbhistprod";
    public function relProdutos(){return $this->belongsTo(tbprod::class);}
    public function relPessoas(){return $this->belongsTo(tbpessoa::class);}}

app>Models>tbpessoa.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class tbpessoa extends Model{
    use HasFactory;
    protected $table="tbpessoa";
    protected $primaryKey="codp";
    public function relHistorias(){return $this->hasMany(tbhistprod::class);}}

app>Models>tbprod.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class tbprod extends Model{
    use HasFactory;
    protected $table="tbprod";
    protected $primaryKey="codprod";
    public function relHistorias(){return $this->hasMany(tbhistprod::class);}}

 

Editado por Frank K Hosaka
Link para o comentário
Compartilhar em outros sites

  • 0

O código que publiquei não funciona, pois eu não segui a nomenclatura sugerida pelo manual do Laravel. A chave primária da tbprod é codprod e não id. A chave primária da tbpessoa é codp e não id. Logo, para o código acima funcionar, ela tem que ser consertada assim:

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class tbhistprod extends Model{
    use HasFactory;
    protected $table="tbhistprod";
    public function relProdutos(){return $this->belongsTo(tbprod::class,'codprod');}
    public function relPessoas(){return $this->belongsTo(tbpessoa::class,'codp');}}

 

Link para o comentário
Compartilhar em outros sites

  • 0

Eu fiz mais um teste, e percebi que não preciso definir a relação da tbprod com a tbhistprod e nem da tbpessoa com a tbhistprod. Eu só preciso definir a relação no Model da tbhistprod com as outras duas tabelas assim:

app>Models>tbhistprod.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class tbhistprod extends Model{
    use HasFactory;
    protected $table="tbhistprod";
    public function produtos(){return $this->belongsTo(tbprod::class,'codprod');}
    public function pessoas(){return $this->belongsTo(tbpessoa::class,'codp');}}

Note que apareceram os campos 'codprod' e 'codp' nas relações, senão o Eloquent iria procurar o campo 'id' como chave primária nas outras tabelas, o que não é o caso.

O controller ficou assim:
 

app>Http>Controllers>DiarioController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\tbhistprod;
class DiarioController extends Controller {
public function detalhe(Request $request){
    $produtos=tbhistprod::with('produtos','pessoas')->where('lcto',$lcto)->get();
    $soma=$produtos->sum('custototal');
    return view('detalhe',compact('detalhe','contas','produtos'),['soma'=>$soma]);}}

E, finalmente, no detalhe.blade.php, para obter o nome do produto, você precisa mencionar a relação assim:

{{{$produtos->produtos->prod}}}

e para obter o nome do fornecedor, assim

{{{$produtos->pessoas->pessoa}}}

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...