cheap dedicated servers

Newton Wagner se desenvolvendo na web

27Mar/086

Relacionamento entre tabelas com ORM do Kohana Framework

Importante: Este artigo refere-se a uma versão antiga do Kohana Framework, que recentemente fez diversas alterações em seu ORM. Se você estiver utilizando a nova versão, favor verificar o Guia do Usuário do Kohana para mais informações.

Achei o post do Adler sobre relacionamento entre tabelas com o Zend Framework bem bacana e didático. Estou me devendo uma olhada no ZF, que já está na versão 1.5.1 (enquanto escrevo este artigo), mas isso deve ficar mais pro final do ano.

Resolvi então fazer uma espécie de série, sobre ORMs dos frameworks. Quem aí trabalhar com CakePHP, Symfony, Doctrine, Lumine ou qualquer outro framework/orm, faça um artigo sobre isso e vamos fazer uma rede de links. Pode ser muito útil pra comunidade, principalmente pra quem procura um framework. Por aqui, vou falar do Kohana framework. Mãos à obra:

No Kohana, para usar o ORM você precisa seguir uma padronização de nomes de tabelas e das chaves estrangeiras, então, nossas tabelas de UF e Cidade ficariam assim:

ufs
id - INT - PRIMARY KEY
nome - Varchar(100)

cidades
id - INT - PRIMARY KEY
nome - Varchar(100)
uf_id - INT - FOREIGN KEY

Sim, as tabelas precisam estar no plural (no padrão americano), e não quero entrar no mérito se isso é bom ou ruim. Continuemos o exemplo mostrando como seriam nossas classes para cada uma das entidades, já montando os arrays para os relacionamentos:

class Uf_Model extends ORM
{
   protected $has_many = array('cidades');
}

class Cidade_Model extends ORM
{
  protected $belongs_to = arary('uf');
}

No Kohana, as classes de modelo devem ter o sufixo "_Model", e aqui extendemos a classe ORM. Aqui uma outra controvérsia. Quando declaramos o array has_many, colocamos a entidade no plural, mas quando declaramos belongs_to, está no singular. Apesar de fazer sentido, é preciso ficar atento pra não confundir as coisas. Você ainda pode ter os seguintes relacionamentos:

  • has_one
  • belongs_to_many
  • has_and_belongs_to_many

Nos resta agora demonstrar um exemplo prático de como trabalhar com as duas entidades. Confesso que gostei muito mais da implementação do belongs_to, que comento mais pra baixo, mas este modelo também é bastante prático. Vejamos um controller de exemplo:

class Index_Controller extends Controller
{
   public function index()
   {
      // instancia o objeto UF com id 1
      $obj_uf = new Uf_Model(1);

      // Pesquisa pelas cidades desta UF
      $cidades = $obj_uf->find_related_cidades();

      // Percorre as cidades exibindo na tela
      foreach ($cidades as $cidade)
      {
        echo $cidade->nome.'<br />';
      }
   }
}

Poderíamos usar o ORM::factory() para recuperar a uf, que usa o method chaining do PHP:

$obj_uf = ORM::factory('uf')->find(1);

Agora vou demonstrar algo que achei muito prático e que poupa bastante tempo de codificação, que é a recuperação do nome da UF a partir de uma cidade, veja este outro exemplo de controller:

class Index_Controller extends Controller
{
   public function index()
   {
      // instancia o objeto Cidade com ID 1
      $obj_cidade = new Cidade_Model(1);

      // Exibindo nome da Cidade e UF na tela
      echo 'Cidade: '. $cidade->nome .'<br />';
      // O objeto uf já é inserido automagicamente no objeto cidade
      echo 'UF: '. $cidade->uf->nome;
   }
}

Isso mesmo que você leu. Não preciso fazer absolutamente nada pra recuperar a UF, o framework faz isso automaticamente através do método mágico __get(). Como eu disse antes, muito prático.

Conclusão

Em um comparativo com o tutorial do Zend Framework, creio que o Kohana cumpriu o seu papel de tornar o desenvolvimento mais ágil, porém, perde em organização e poder das funcionalidades de mapeamento dos objetos.

E vocês, o que acharam dessa implementação?

Artigos Relacionados:

Tagged as: Leave a comment
Comments (6) Trackbacks (0)
  1. Excelente ideia Newton, uma otima forma de fazer um comparativo dos frame facilitar a vida de todos.

    Uma duvida, no final você falou que ele busca a uf automagicamente, isso ocorre quando vc faz $cidade->uf->nome ou já quando carrega a cidade?

    Porque se for direto quando carrega pode rolar um overhead sinistro para bancos maiores. Se não então é excelente solução mesmo.

  2. Rafael, ele carrega apenas quando é chamado, isto é, você carregou a cidade, ele não trouxe a UF neste momento. Ele só vai ser carregando quando você usar $cidade->uf->… .

  3. Legal, vamos ajudar mais a comunidade KOHANA …… mais tutoriais em BR ……. apesar da doc english ser muito boa muita gente precisa de mais explicações …..

  4. Newton,

    Ainda funciona essse teu código. Aqui deu pau.
    Mudou algo para as versões recentes do Kohana?

    Valeu

  5. O erro é:
    Invalid method find_related_cidades called in Uf_Model

  6. Olá Fagner,
    Não tenho acompanhado a evolução do Kohana, mas pelo que sei houveram sim muitas alterações no ORM do framework.
    Não posso prometer uma data, mas vou ver se pesquiso como ficou pra atualizar esse post, ok?


Leave a comment

(required)

No trackbacks yet.