Observação: Este tutorial refere-se ao Laravel-4-BETA, estando totalmente DESATUALIZADO para a versão atual. Muita coisa mudou no framework…
Nossas tasks e listas se relacionam.
Criamos esse relacionamento na migration do post anterior, quando criamos a tabela listas e definimos na tabela tasks a coluna list_id, formalizando um relacionamento de 1 para N (1:N).
No bom português a gente pode dizer assim “uma lista possui várias tasks” e “uma task deve ser de uma lista”.
Mas como o Laravel 4 entende isso?
Utilizando os Models
Uma das utilidades das classes models no Laravel 4 é definir o relacionamento entre as tabelas para que possamos utilizá-lo facilmente com o Eloquent.
Lista Possui Tasks
Primeiro vamos definir o relaciomento de paternidade.
No caso, o relacionamento é de OneToMany.
Para isso vou alterar o modelo models/Lista.php
<?php class Lista extends Eloquent { public function tasks() { return $this->hasMany('Task'); } }
Explico já, começou a luta do Jones vs Sonnen… Vai ser surra LOL
Vish… Foi mais fácil que programar em Laravel… deu nem pro começo…
Então, a vibe é o seguinte: definimos uma função dentro da definição da Classe (model) Lista.
O que esse método faz é o seguinte, quando chamarmos $objeto_lista->tasks(); será retornado os “filhos” da lista.
Porém o nosso código tem um problema.
O Laravel assume que lá na tabela “filha” exista uma coluna nesse padrão: “tabelapai_id”.
No nosso caso, o Laravel está assumindo que na tabela task exista uma coluna chamada lista_id.
Se vocês não se lembram do post anterior, na tabela task criamos a coluna list_id e não lista_id como o Laravel espera.
Nesse caso a gente pode fazer uma migration para corrigir isso ou pode fazer uma pequena alteração no nosso código para informar o Laravel qual é a coluna correta.
Eu prefiro fazer a alteração.
Mas fica a gosto 😀
<?php class Lista extends Eloquent { public funtion tasks() { return $this->hasMany('Task', 'list_id'); } }
Foi mais difícil que bater no Chael Sonnen 😛
Task é de uma lista
Definimos na classe Lista o relacionamento da tabela Listas com a tabela tasks, dando-nos a facilidade de encontrar as tasks relacionadas a partir de um objeto da lista.
Agora vamos definir o relacionamento na classe Task para podermos, a partir de um objeto Task, identificar quem é a Lista pai.
Então, alterando o arquivo models/task.php
<?php class Task extends Eloquent { public function lista() { return $this->belongsTo('Lista', 'list_id'); } }
Tranquilo demais, né?
No próximo post mostro como utilizar o que acabamos de criar.
Olá, queria pedir ajuda para resolver esse problema: Tenho duas tabelas: membros e contestwinners
membros:
id
login
fname
contestwinners
id
uid
place
type
rdate
status
quero selecionar tudo em ordem de colocação (place) da tabela contestwinners e preciso pegar o nome (fname) do usuario na tabela membros para exibir uma lista (juntando as duas tabelas) em ordem de colocação (place). Você pode me ajudar a montar esse model, controller e view?
Opa Hans.
Fazer isso com o Laravel é tranquilo.
Primeiro você precisa definir o relacionamento.
E depois, fazer uso dele.
Primeiro, entendi que o relacionamento é Membros(1 – n)contestwinners.
Pelo que percebi, o uid da tabela contestwinners é a chave estrangeira id da tabela membros.
——— UTILIZANDO ELOQUENT ———
De acordo com o meu entendimento, se foi correto, você pode fazer os Models assim:
Model para a tabela Membros: http://pastebin.com/9xkMR0WL
Model para a tabela Contestwinners: http://pastebin.com/8kTHKviU
Para pegar todos os contestwinners: $vencedores = Contestwinner::all();
Para pegar todos os contestwinners ordenados: $vencedores = Contestwinner::all()->orderBy(‘place’, ‘ASC’)->get()
E ai, o que é retornado por qualquer uma das queries é uma lista/array de objetos do tipo Contestwinner, onde você pode fazer acesso aos elementos de cada objeto dentro de um loop.
Por exemplo:
foreach ($vencedores as $vencedor) echo $vencedor->place;
Como já definimos o relacionamento, dá para utilizá-lo dessa forma para pegar o nome do usuário:
foreach ($vencedores as $vencedor) echo $vencedor->membro->fname;
——— UTILIZANDO O QUERY BUILDER (Fluent) ———
Dá pra fazer assim:
$vencedores = DB::table(‘contestwinners’)->join(‘membros’, ‘uid’, ‘=’, ‘id’)->orderBy(‘place’, ‘ASC’)->get();
ou assim para escolher só alguns campos:
$vencedores = DB::table(‘contestwinners’)->join(‘membros’, ‘uid’, ‘=’, ‘id’)->orderBy(‘place’, ‘ASC’)->select(‘place’, ‘fname’);
Em ambos os casos, o loop para exibir é o mesmo:
foreach ($vencedores as $vencedor) echo $vencedor->place;
Fiquei interessado em como alterar a tabela usando migrations. Altero o migration anterior ou crio um novo? Em qualquer caso, como proceder?
Você deve criar um novo script de migração, análogo ao que fizemos aqui, e nesse script de migração você define a inserção desta sua nova coluna.
Então, você executa o comando para realizar a migração.
Vide a documentação: http://laravel.com/docs/migrations
Primeiro parabéns pelos posts, tá sendo de ajuda pra muita gente. Deixa eu só tirar uma dúvida:
Eu posso criar 2 foreignkeys relacionadas a uma só tabela?
tipo, eu tenho uma tabela User, e outra Avaliacao… quando o User for cadastrar a Avaliacao, eu quero que salve o Id do User(Aluno) e do User(Professor).
Obs: todos os usuários logam na mesma tabela, o que diferencia é o campo perfil.
Pergunta: consigo fazer isso com o laravel, ou melhor criar uma tabela Auno separada pra fazer esse tipo de relacionamento?
Consegue sim.
Na documentação temos esse caso exemplificado.
Veja se esse é o seu caso:
http://laravel.com/docs/eloquent#working-with-pivot-tables