Tela de Cadastro com Many-to-Many
Autor: Luciano Borges | Publicado: 2009-11-20T19:22:00-03:00

* Esse post foi baseado no tutorial de Jeffrey Hicks e no Railscast número 47.A idéia deste post é mostrar na prática como fazer um tela de cadastro havendo uma relação many-to-many. Para criar esse tutorial estou usando o Netbeans 6.7.1 e o banco de dados MySQL.Primeiro passo é criar um projeto Rails chamado escola.Esse exemplo mostra uma parte do que seria um sistema acadêmico, onde eu tenho uma tabela de alunos, disciplinas e uma relação alunos por disciplina. Para trabalhar com o padrão do Rails seguiremos a convenção de nome para as tabelas e os campos.Repare que o nomes das tabelas estão no plural.Os campos chaves são chamados de id.A tabela de relacionamento é na ordem alfabética.O campo de relacionamento é o nome da entidade no singular seguido de _id.O segundo passo é gerar os scaffolds para aluno e disciplina, abaixo mostro a tela de gerar o scaffold do Netbeans 6.7.1 para o model aluno, a mesma operação deve ser feita para disciplina (lembre-se que o nome do model deve ser no singular).Altere os models aluno.rb e disciplina adicionando o método has_and_belongs_to_many conforme imagem abaixo.Essa alteração diz que disciplina tem e pertence a muitos alunos e aluno tem e pertence a muitas disciplinas. O método has_and_belongs_to_many é que faz o relacionamento n:n.Como precisaremos de uma tabela de relacionamento, vamos criar uma migração de nome create_alunos_disciplinas para essa tabela.Edite o código dessa nova migration conforme imagem abaixo:Essa tabela não terá a chave primário id. Rode as migrations.Para permitir que o usuário informe um aluno com várias disciplinas, vamos utilizar checkbox múltiplos. O nosso formulário será gerado dinamicamente a partir das disciplinas cadastradas no banco de dados. Nossa view vai depender do controller alunos_controller para carregar as disciplinas, altere o método new e edit do controller alunos_controller.rb conforme imagem abaixo.Agora iremos customizar as views edit e new de alunos. Vamos fazer isso em um único local, ou seja, na partial _form.rhtml - para isso crie dentro de views/alunos o arquivo _form.rhtml e coloque o código abaixo.Nessa partial colocamos um for para carregar os checkbox com os valores e nomes das disciplinas disponibilizadas pelo objeto @disciplinas que foi passado nos métodos new e edit do controller. Repare que o botão f.submit tá com nome button, esse nome é passado como parâmetro na chamada da partial nas views new e edit e o :disable_with serve para desabilitar o botão com a mensagem "Aguarde..." enquanto a requisição estiver ocorrendo. Abaixo o código das views alteradas, veja que na chamada da partial, passamos o parâmetro :button com o texto que vai aparecer nos botões.Vamos alterar agora a view index de alunos para poder mostrar as disciplinas que o mesmo está associado.Os métodos update e create de alunos_controller.rb recebem requisições das views edit e new. Para armazenar o relacionamento precisamos converter disciplinas_ids para objetos Disciplina com Disciplina.find(@params[:disciplina_ids]) if @params[:disciplina_ids]. O if previne erros de objetos nulos quando o aluno não estiver associado a alguma disciplina.Agora é só testar!!!!  Veja algumas telas abaixo.