sexta-feira, 20 de novembro de 2009

Tela de Cadastro com Many-to-Many

* 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.


Nenhum comentário:

Postar um comentário

Obrigado pela visita!