ToDoVel [Parte 14] Relacionamento Entre as Tabelas

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.

9 thoughts on “ToDoVel [Parte 14] Relacionamento Entre as Tabelas

  1. 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?

    1. 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;

  2. 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?

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *