8

Auto-relacionamento em Rails

Posted March 19th, 2009 in Desenvolvimento and tagged , , , , , by felipepavao

Finalmente o primeiro post sobre Rails. Essa dica é muito legal e prática para quem quer fazer auto-relaciomento com Rails. Estou postando porque não foi tão fácil encontrar a solução. Para facilitar, vamos exemplificar:

Vamos supor que em nosso sistema (um blog, por exemplo) temos categorias. E categorias podem possuir categorias filhas. Temos aí um auto-relacionamento para fazer, certo ?

No Rails, isso é muito fácil. No esquema das migrations, deveríamos ter algo parecido com isso:

class CreateCategories < ActiveRecord::Migration
  def self.up
    create_table :categories do |t|
      t.string :name
      t.string :description
      t.integer :father_id
	end
  end
 
  def self.down
    drop_table :categories
  end
end

A coluna father_id indica a o ID de uma categoria pai. Seria como uma Foreign Key. Agora precisamos definir o relacionamento no Model para que o Rails possa compreender a tabela que criamos.

class Category < ActiveRecord::Base
	has_many :children, :class_name => "Category", :foreign_key => "father_id"
	belongs_to :father, :class_name => "Category"
end

Essas duas linhas de código significam o seguinte:

  • A primeira linha, indica que Category tem filhos, utilizando o Model Category e chave estrangeira father_id;
  • A segunda linha diz que o mesmo Model Category pertence a um Category, estabelecendo aí o auto-relacionamento.

A partir daí, você já pode brincar e descobrir os filhos de um Category pai usando @category.children. Para descobrir o pai de um Category, use @category.father.

Para quem quiser aprender mais sobre relacionamentos no Rails, acesse o Guia Rails, ainda na versão em Inglês.  Em breve haverá uma versão em português. Assim que sair eu anunciarei por aqui.

8 Responses so far.

  1. Mateus says:

    Valeu pela iniciativa Felipe.

    Ótimo artigo.

    @mateus,

    obrigado pela visita.

  2. Renato says:

    Olá.
    E como faço para acessar os registros do pai no console?

    Category.children por exemplo não funciona.

    Abraços

  3. Bianca says:

    Eu fiz exatamente isso, fiz a migração, mas na hora de selecionar os filhos em um multiple select, ele reconhece os filhos como strings e não como filhos… Daí dá um ActiveRecord::AssociationTypeMismatch :(

  4. Luiz Cezer says:

    Muito bom cara, seus posts me ajudam muito =)

    • felipepavao says:

      Luiz,

      obrigado por visitar meu site. Espero ajudar cada vez.

      Abs!

      • Luiz Cezer says:

        E como ficaria isso a nivel de controller e view?
        supondo que eu queira criar um tela com um combox
        pra trazer as categorias onde father_id é Null
        (que são as de hierarquia mais alta)
        e um campo pra cadastrar uma nova categoria, se eu selecionar
        um pai, quer dizer que ela é filha do mesmo, se não quer
        dizer que ela é uma nova categoria pai. como ficaria?

        • felipepavao says:

          Luiz,

          você vai fazer uma busca onde father_id é nil. Não tem mistério.
          E sobre cadastrar, é um processo parecido. Infelizmente eu não tenho tempo agora para criar um código de exemplo, mas é um formulário simples, com um combo representando father_id. Se vc não escolher ninguém, ele será considerado pai. Se escolher, a nova entrada será filha de um pai.

          Abs.

          • Luiz Cezer says:

            Eu implementei isso, é é muito simples, MUITO mesmo, só gerar o combo trazendo as categorias e mais nada, continue com os posts, abraços!

Leave a Reply