Skip to content
julho 24, 2008 / cassiomarques

Usando a opção :through no has_many

Que os métodos para associações entre models do ActiveRecord quebra um galhão todo mundo sabe. O interessante é que quando não conhecemos e/ou estamos habituados a utilizar os recursos do ActiveRecord, existe uma forte tendência a não utilizar estes métodos para associação ou ainda escrever métodos de pesquisa com sentenças SQL puras, usando o famigerado find_by_sql. O fato é que sempre que possível deve-se usar os recursos disponíveis pelo AR, pois isso gera um código mais limpo, legível e, para os puristas de plantão, mais OO.

O AR tem muitos recursos para facilitar a associação entre os models e tornar automáticas (ou quase) buscas que de outra forma exigiriam a criação de sentença SQL complexas cheias de joins. Um destes recursos é a opção has_many, através da qual podemos dizer coisas como “um carro tem muitas peças”.

class Peca < ActiveRecord::Base belongs_to :carro end class Carro < ActiveRecord::Base has_many :pecas end [/source] E podemos usar isso assim [source language="ruby"] @carro = Carro.find(1) @pecas = @carro.pecas # <= retorna uma lista de objetos da classe Peca [/source] Essa busca é feita através das chaves primárias/estrangeiras presentes nas tabelas. Na verdade voc6e não precisa ter essas contraints realmente criadas no banco, desde que obedeça certos critérios de nomenclatura para as colunas das suas tabelas. No exemplo acima, o Rails vai assumir que uma coluna chamada carro_id na tabela pecas indica a coluna id da tabela carros e assim relaciona os dois models. Um exemplo mais complexo seria o caso onde temos um esquema do tipo:

  • Uma empresa tem vários clientes
  • Cada cliente possui várias faturas

Neste cenário, podemos querer pesquisar todas as faturas de uma determinada empresa. O problema é que não existe na tabela faturas uma coluna chamada empresa_id. Como o Rails vai então relacionar as coisas?
A tabela clientes possui essa coluna empresa_id!
Podemos então utilizar a opção :through da associação has_many, e fazer com que o ActiveRecord utilize um join para associar as tabelas “empresas” e “faturas” através da tabela “clientes”. Assim:

class Empresa < ActiveRecord::Base has_many :clientes has_many :faturas, :through => :clientes
end

class Cliente < ActiveRecord::Base belongs_to :empresa has_many :faturas end class Fatura < ActiveRecord::Base belongs_to :cliente end [/source] E podemos fazer coisas como [source language="ruby"] @empresa = Empresa.find(1) @faturas = @empresa.faturas [/source] O Rails vai pesquisar o banco usando um SQL mais ou menos assim (que você não precisou escrever!): [source language="sql"] SELECT "faturas".* FROM "faturas" INNER JOIN clientes ON faturas.cliente_id = clientes.id WHERE (("clientes".empresa_id = 1)) [/source]

5 Comentários

Deixe um comentário
  1. Luiz Carvalho / out 22 2008 10:44 pm

    Cassio como você faz para colocar códigos em seus posts?
    vlw

  2. cassiomarques / out 23 2008 2:54 am

    Suponha que você queira colocar um código na linguagem xpto

    …seu código…

    isso funciona aqui no wordpress, em outro engine de blog eu já não sei…

  3. Luiz Arão Araújo Carvalho / out 23 2008 4:30 am

    Opa.
    vlw pela resposta rapida.
    então tbm uso WordPress(http://www.maxonrails.wordpress.com)
    mas aqui ele não iterpreta essa tag ai não.
    você utilizou algum tipo de plugin?

    Obrigado.

  4. cassiomarques / out 23 2008 4:43 am

    Nenhum plugin. quando vcê está escrevendo o post, o editor do WordPress possui duas abas, uma para o modo “visual” e o outro o código (modo “html”). tem que ser no modo pra código, no modo visual ele vai ignorar as tags mesmo.

  5. Luiz Arão Araújo Carvalho / out 23 2008 3:15 pm

    KKKKK
    eu que estava doido mesmo Cassio.
    sim, eu coloquei na aba HTML, mas
    eu espera ver o código já pronto na aba visual
    quando eu mudava de aba ele estava igual O.o
    ai eu pensei que n estava funcionando.

    Obrigado Cassio.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: