SlideShare uma empresa Scribd logo
Ruby On Rails
9 de Julho de 2008
Conteúdo
I Sobre essa apostila 3
II Informações Básicas 5
III GNU Free Documentation License 10
IV Ruby on Rails 19
1 O que é o curso Ruby on Rails 20
2 Plano de ensino 21
2.1 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2 Público Alvo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.3 Pré-requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.4 Descrição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.5 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.6 Cronograma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.7 Programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.8 Avaliação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.9 Bibliografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3 Iniciando o Ruby on Rails 24
3.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.2 Instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.3 Configurando Banco de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4 Gerando Migrações e Modelos de Dados 30
4.1 Gerando Migrações e Modelos de dados I . . . . . . . . . . . . . . . . . . . . . . . . 30
5 MVC e CONTROLLER 39
5.1 MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.2 O primeiro controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6 Layouts e Roteamento 43
6.1 Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.2 Roteamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
7 Scaffolding e Validações 48
7.1 Scaffolding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
7.2 Validações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
8 Segundo Controller 56
8.1 Início . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
9 Extendendo um modelo de dados e Helpers 69
9.1 Extendendo um modelo de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
9.2 Usando Helpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
10 Relacionamentos 75
10.1 Início . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
11 Belongs to 81
11.1 Belongs to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
12 Has many, has one, has many through 91
12.1 Has many . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
12.2 Has one . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
12.3 Has many, trough . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
2
Parte I
Sobre essa apostila
3
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Conteúdo
O conteúdo dessa apostila é fruto da compilação de diversos materiais livres publicados na in-
ternet, disponíveis em diversos sites ou originalmente produzido no CDTC em http://www.cdtc.org.br.
O formato original deste material bem como sua atualização está disponível dentro da licença
GNU Free Documentation License, cujo teor integral encontra-se aqui reproduzido na seção de
mesmo nome, tendo inclusive uma versão traduzida (não oficial).
A revisão e alteração vem sendo realizada pelo CDTC (suporte@cdtc.org.br), desde outubro
de 2006. Criticas e sugestões construtivas são bem-vindas a qualquer tempo.
Autores
A autoria deste conteúdo, atividades e avaliações é de responsabilidade de Diego de Aquino
Soares (diego@cdtc.org.br).
O texto original faz parte do projeto Centro de Difusão de Tecnolgia e Conhecimento, que vem
sendo realizado pelo ITI em conjunto com outros parceiros institucionais, atuando em conjunto
com as universidades federais brasileiras que tem produzido e utilizado Software Livre, apoiando
inclusive a comunidade Free Software junto a outras entidades no país.
Informações adicionais podem ser obtidas atréves do email ouvidoria@cdtc.org.br, ou da
home page da entidade, através da URL http://www.cdtc.org.br.
Garantias
O material contido nesta apostila é isento de garantias e o seu uso é de inteira responsabi-
lidade do usuário/leitor. Os autores, bem como o ITI e seus parceiros, não se responsabilizam
direta ou indiretamente por qualquer prejuízo oriundo da utilização do material aqui contido.
Licença
Copyright ©2006,Diego de Aquino Soares (diego@cdtc.org.br).
Permission is granted to copy, distribute and/or modify this document under the terms
of the GNU Free Documentation License, Version 1.1 or any later version published by
the Free Software Foundation; with the Invariant Chapter being SOBRE ESSA APOS-
TILA. A copy of the license is included in the section entitled GNU Free Documentation
License.
4
Parte II
Informações Básicas
5
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Sobre o CDTC
Objetivo Geral
O Projeto CDTC visa a promoção e o desenvolvimento de ações que incentivem a dissemina-
ção de soluções que utilizem padrões abertos e não proprietários de tecnologia, em proveito do
desenvolvimento social, cultural, político, tecnológico e econômico da sociedade brasileira.
Objetivo Específico
Auxiliar o Governo Federal na implantação do plano nacional de software não-proprietário e
de código fonte aberto, identificando e mobilizando grupos de formadores de opinião dentre os
servidores públicos e agentes políticos da União Federal, estimulando e incentivando o mercado
nacional a adotar novos modelos de negócio da tecnologia da informação e de novos negócios
de comunicação com base em software não-proprietário e de código fonte aberto, oferecendo
treinamento específico para técnicos, profissionais de suporte e funcionários públicos usuários,
criando grupos de funcionários públicos que irão treinar outros funcionários públicos e atuar como
incentivadores e defensores de produtos de software não proprietários e código fonte aberto, ofe-
recendo conteúdo técnico on-line para serviços de suporte, ferramentas para desenvolvimento de
produtos de software não proprietários e de seu código fonte livre, articulando redes de terceiros
(dentro e fora do governo) fornecedoras de educação, pesquisa, desenvolvimento e teste de pro-
dutos de software livre.
Guia do aluno
Neste guia, você terá reunidas uma série de informações importantes para que você comece
seu curso. São elas:
• Licenças para cópia de material disponível
• Os 10 mandamentos do aluno de Educação a Distância
• Como participar dos fóruns e da wikipédia
• Primeiros passos
É muito importante que você entre em contato com TODAS estas informações, seguindo o
roteiro acima.
Licença
Copyright ©2006, Diego de Aquino Soares (diego@cdtc.org.br).
6
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
É dada permissão para copiar, distribuir e/ou modificar este documento sob os termos
da Licença de Documentação Livre GNU, Versão 1.1 ou qualquer versão posterior
publicada pela Free Software Foundation; com o Capítulo Invariante SOBRE ESSA
APOSTILA. Uma cópia da licença está inclusa na seção entitulada "Licença de Docu-
mentação Livre GNU".
Os 10 mandamentos do aluno de educação online
• 1. Acesso a Internet: ter endereço eletrônico, um provedor e um equipamento adequado é
pré-requisito para a participação nos cursos a distância.
• 2. Habilidade e disposição para operar programas: ter conhecimentos básicos de Informá-
tica é necessário para poder executar as tarefas.
• 3. Vontade para aprender colaborativamente: interagir, ser participativo no ensino a distân-
cia conta muitos pontos, pois irá colaborar para o processo ensino-aprendizagem pessoal,
dos colegas e dos professores.
• 4. Comportamentos compatíveis com a etiqueta: mostrar-se interessado em conhecer seus
colegas de turma respeitando-os e fazendo ser respeitado pelo mesmo.
• 5. Organização pessoal: planejar e organizar tudo é fundamental para facilitar a sua revisão
e a sua recuperação de materiais.
• 6. Vontade para realizar as atividades no tempo correto: anotar todas as suas obrigações e
realizá-las em tempo real.
• 7. Curiosidade e abertura para inovações: aceitar novas idéias e inovar sempre.
• 8. Flexibilidade e adaptação: requisitos necessário a mudança tecnológica, aprendizagens
e descobertas.
• 9. Objetividade em sua comunicação: comunicar-se de forma clara, breve e transparente é
ponto-chave na comunicação pela Internet.
• 10. Responsabilidade: ser responsável por seu próprio aprendizado. O ambiente virtual não
controla a sua dedicação, mas reflete os resultados do seu esforço e da sua colaboração.
Como participar dos fóruns e Wikipédia
Você tem um problema e precisa de ajuda?
Podemos te ajudar de 2 formas:
A primeira é o uso dos fóruns de notícias e de dúvidas gerais que se distinguem pelo uso:
O fórum de notícias tem por objetivo disponibilizar um meio de acesso rápido a informações
que sejam pertinentes ao curso (avisos, notícias). As mensagens postadas nele são enviadas a
7
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
todos participantes. Assim, se o monitor ou algum outro participante tiver uma informação que
interesse ao grupo, favor postá-la aqui.
Porém, se o que você deseja é resolver alguma dúvida ou discutir algum tópico específico do
curso, é recomendado que você faça uso do Fórum de dúvidas gerais que lhe dá recursos mais
efetivos para esta prática.
. O fórum de dúvidas gerais tem por objetivo disponibilizar um meio fácil, rápido e interativo
para solucionar suas dúvidas e trocar experiências. As mensagens postadas nele são enviadas
a todos participantes do curso. Assim, fica muito mais fácil obter respostas, já que todos podem
ajudar.
Se você receber uma mensagem com algum tópico que saiba responder, não se preocupe com a
formalização ou a gramática. Responda! E não se esqueça de que antes de abrir um novo tópico
é recomendável ver se a sua pergunta já foi feita por outro participante.
A segunda forma se dá pelas Wikis:
Uma wiki é uma página web que pode ser editada colaborativamente, ou seja, qualquer par-
ticipante pode inserir, editar, apagar textos. As versões antigas vão sendo arquivadas e podem
ser recuperadas a qualquer momento que um dos participantes o desejar. Assim, ela oferece um
ótimo suporte a processos de aprendizagem colaborativa. A maior wiki na web é o site "Wikipé-
dia", uma experiência grandiosa de construção de uma enciclopédia de forma colaborativa, por
pessoas de todas as partes do mundo. Acesse-a em português pelos links:
• Página principal da Wiki - http://pt.wikipedia.org/wiki/
Agradecemos antecipadamente a sua colaboração com a aprendizagem do grupo!
Primeiros Passos
Para uma melhor aprendizagem é recomendável que você siga os seguintes passos:
• Ler o Plano de Ensino e entender a que seu curso se dispõe a ensinar;
• Ler a Ambientação do Moodle para aprender a navegar neste ambiente e se utilizar das
ferramentas básicas do mesmo;
• Entrar nas lições seguindo a seqüência descrita no Plano de Ensino;
• Qualquer dúvida, reporte ao Fórum de Dúvidas Gerais.
Perfil do Tutor
Segue-se uma descrição do tutor ideal, baseada no feedback de alunos e de tutores.
O tutor ideal é um modelo de excelência: é consistente, justo e profissional nos respectivos
valores e atitudes, incentiva mas é honesto, imparcial, amável, positivo, respeitador, aceita as
idéias dos estudantes, é paciente, pessoal, tolerante, apreciativo, compreensivo e pronto a ajudar.
8
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
A classificação por um tutor desta natureza proporciona o melhor feedback possível, é crucial, e,
para a maior parte dos alunos, constitui o ponto central do processo de aprendizagem.’ Este tutor
ou instrutor:
• fornece explicações claras acerca do que ele espera, e do estilo de classificação que irá
utilizar;
• gosta que lhe façam perguntas adicionais;
• identifica as nossas falhas, mas corrige-as amavelmente’, diz um estudante, ’e explica por-
que motivo a classificação foi ou não foi atribuída’;
• tece comentários completos e construtivos, mas de forma agradável (em contraste com um
reparo de um estudante: ’os comentários deixam-nos com uma sensação de crítica, de
ameaça e de nervosismo’)
• dá uma ajuda complementar para encorajar um estudante em dificuldade;
• esclarece pontos que não foram entendidos, ou corretamente aprendidos anteriormente;
• ajuda o estudante a alcançar os seus objetivos;
• é flexível quando necessário;
• mostra um interesse genuíno em motivar os alunos (mesmo os principiantes e, por isso,
talvez numa fase menos interessante para o tutor);
• escreve todas as correções de forma legível e com um nível de pormenorização adequado;
• acima de tudo, devolve os trabalhos rapidamente;
9
Parte III
GNU Free Documentation License
10
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
(Traduzido pelo João S. O. Bueno através do CIPSGA em 2001)
Esta é uma tradução não oficial da Licençaa de Documentação Livre GNU em Português
Brasileiro. Ela não é publicada pela Free Software Foundation, e não se aplica legalmente a dis-
tribuição de textos que usem a GFDL - apenas o texto original em Inglês da GNU FDL faz isso.
Entretanto, nós esperamos que esta tradução ajude falantes de português a entenderem melhor
a GFDL.
This is an unofficial translation of the GNU General Documentation License into Brazilian Por-
tuguese. It was not published by the Free Software Foundation, and does not legally state the
distribution terms for software that uses the GFDL–only the original English text of the GFDL does
that. However, we hope that this translation will help Portuguese speakers understand the GFDL
better.
Licença de Documentação Livre GNU Versão 1.1, Março de 2000
Copyright (C) 2000 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
É permitido a qualquer um copiar e distribuir cópias exatas deste documento de licença, mas
não é permitido alterá-lo.
INTRODUÇÃO
O propósito desta Licença é deixar um manual, livro-texto ou outro documento escrito "livre"no
sentido de liberdade: assegurar a qualquer um a efetiva liberdade de copiá-lo ou redistribui-lo,
com ou sem modificações, comercialmente ou não. Secundariamente, esta Licença mantém
para o autor e editor uma forma de ter crédito por seu trabalho, sem ser considerado responsável
pelas modificações feitas por terceiros.
Esta Licença é um tipo de "copyleft"("direitos revertidos"), o que significa que derivações do
documento precisam ser livres no mesmo sentido. Ela complementa a GNU Licença Pública Ge-
ral (GNU GPL), que é um copyleft para software livre.
Nós fizemos esta Licença para que seja usada em manuais de software livre, por que software
livre precisa de documentação livre: um programa livre deve ser acompanhado de manuais que
provenham as mesmas liberdades que o software possui. Mas esta Licença não está restrita a
manuais de software; ela pode ser usada para qualquer trabalho em texto, independentemente
do assunto ou se ele é publicado como um livro impresso. Nós recomendamos esta Licença prin-
cipalmente para trabalhos cujo propósito seja de introdução ou referência.
APLICABILIDADE E DEFINIÇÕES
Esta Licença se aplica a qualquer manual ou outro texto que contenha uma nota colocada pelo
detentor dos direitos autorais dizendo que ele pode ser distribuído sob os termos desta Licença.
11
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
O "Documento"abaixo se refere a qualquer manual ou texto. Qualquer pessoa do público é um
licenciado e é referida como "você".
Uma "Versão Modificada"do Documento se refere a qualquer trabalho contendo o documento
ou uma parte dele, quer copiada exatamente, quer com modificações e/ou traduzida em outra
língua.
Uma "Seção Secundária"é um apêndice ou uma seção inicial do Documento que trata ex-
clusivamente da relação dos editores ou dos autores do Documento com o assunto geral do
Documento (ou assuntos relacionados) e não contém nada que poderia ser incluído diretamente
nesse assunto geral (Por exemplo, se o Documento é em parte um livro texto de matemática, a
Seção Secundária pode não explicar nada de matemática).
Essa relação poderia ser uma questão de ligação histórica com o assunto, ou matérias relaci-
onadas, ou de posições legais, comerciais, filosóficas, éticas ou políticas relacionadas ao mesmo.
As "Seções Invariantes"são certas Seções Secundárias cujos títulos são designados, como
sendo de Seções Invariantes, na nota que diz que o Documento é publicado sob esta Licença.
Os "Textos de Capa"são certos trechos curtos de texto que são listados, como Textos de Capa
Frontal ou Textos da Quarta Capa, na nota que diz que o texto é publicado sob esta Licença.
Uma cópia "Transparente"do Documento significa uma cópia que pode ser lida automatica-
mente, representada num formato cuja especificação esteja disponível ao público geral, cujos
conteúdos possam ser vistos e editados diretamente e sem mecanismos especiais com editores
de texto genéricos ou (para imagens compostas de pixels) programas de pintura genéricos ou
(para desenhos) por algum editor de desenhos grandemente difundido, e que seja passível de
servir como entrada a formatadores de texto ou para tradução automática para uma variedade
de formatos que sirvam de entrada para formatadores de texto. Uma cópia feita em um formato
de arquivo outrossim Transparente cuja constituição tenha sido projetada para atrapalhar ou de-
sencorajar modificações subsequentes pelos leitores não é Transparente. Uma cópia que não é
"Transparente"é chamada de "Opaca".
Exemplos de formatos que podem ser usados para cópias Transparentes incluem ASCII sim-
ples sem marcações, formato de entrada do Texinfo, formato de entrada do LaTex, SGML ou XML
usando uma DTD disponibilizada publicamente, e HTML simples, compatível com os padrões, e
projetado para ser modificado por pessoas. Formatos opacos incluem PostScript, PDF, formatos
proprietários que podem ser lidos e editados apenas com processadores de texto proprietários,
SGML ou XML para os quais a DTD e/ou ferramentas de processamento e edição não estejam
disponíveis para o público, e HTML gerado automaticamente por alguns editores de texto com
finalidade apenas de saída.
A "Página do Título"significa, para um livro impresso, a página do título propriamente dita,
mais quaisquer páginas subsequentes quantas forem necessárias para conter, de forma legível,
o material que esta Licença requer que apareça na página do título. Para trabalhos que não
tenham uma página do título, "Página do Título"significa o texto próximo da aparição mais proe-
minente do título do trabalho, precedendo o início do corpo do texto.
12
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
FAZENDO CÓPIAS EXATAS
Você pode copiar e distribuir o Documento em qualquer meio, de forma comercial ou não
comercial, desde que esta Licença, as notas de copyright, e a nota de licença dizendo que esta
Licença se aplica ao documento estejam reproduzidas em todas as cópias, e que você não acres-
cente nenhuma outra condição, quaisquer que sejam, às desta Licença.
Você não pode usar medidas técnicas para obstruir ou controlar a leitura ou confecção de
cópias subsequentes das cópias que você fizer ou distribuir. Entretanto, você pode aceitar com-
pensação em troca de cópias. Se você distribuir uma quantidade grande o suficiente de cópias,
você também precisa respeitar as condições da seção 3.
Você também pode emprestar cópias, sob as mesmas condições colocadas acima, e também
pode exibir cópias publicamente.
FAZENDO CÓPIAS EM QUANTIDADE
Se você publicar cópias do Documento em número maior que 100, e a nota de licença do
Documento obrigar Textos de Capa, você precisará incluir as cópias em capas que tragam, clara
e legivelmente, todos esses Textos de Capa: Textos de Capa da Frente na capa da frente, e
Textos da Quarta Capa na capa de trás. Ambas as capas também precisam identificar clara e
legivelmente você como o editor dessas cópias. A capa da frente precisa apresentar o titulo com-
pleto com todas as palavras do título igualmente proeminentes e visíveis. Você pode adicionar
outros materiais às capas. Fazer cópias com modificações limitadas às capas, tanto quanto estas
preservem o título do documento e satisfaçam a essas condições, pode ser tratado como cópia
exata em outros aspectos.
Se os textos requeridos em qualquer das capas for muito volumoso para caber de forma
legível, você deve colocar os primeiros (tantos quantos couberem de forma razoável) na capa
verdadeira, e continuar os outros nas páginas adjacentes.
Se você publicar ou distribuir cópias Opacas do Documento em número maior que 100, você
precisa ou incluir uma cópia Transparente que possa ser lida automaticamente com cada cópia
Opaca, ou informar, em ou com, cada cópia Opaca a localização de uma cópia Transparente
completa do Documento acessível publicamente em uma rede de computadores, a qual o público
usuário de redes tenha acesso a download gratuito e anônimo utilizando padrões públicos de
protocolos de rede. Se você utilizar o segundo método, você precisará tomar cuidados razoavel-
mente prudentes, quando iniciar a distribuição de cópias Opacas em quantidade, para assegurar
que esta cópia Transparente vai permanecer acessível desta forma na localização especificada
por pelo menos um ano depois da última vez em que você distribuir uma cópia Opaca (direta-
mente ou através de seus agentes ou distribuidores) daquela edição para o público.
É pedido, mas não é obrigatório, que você contate os autores do Documento bem antes de
redistribuir qualquer grande número de cópias, para lhes dar uma oportunidade de prover você
com uma versão atualizada do Documento.
13
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
MODIFICAÇÕES
Você pode copiar e distribuir uma Versão Modificada do Documento sob as condições das se-
ções 2 e 3 acima, desde que você publique a Versão Modificada estritamente sob esta Licença,
com a Versão Modificada tomando o papel do Documento, de forma a licenciar a distribuição
e modificação da Versão Modificada para quem quer que possua uma cópia da mesma. Além
disso, você precisa fazer o seguinte na versão modificada:
A. Usar na Página de Título (e nas capas, se houver alguma) um título distinto daquele do Do-
cumento, e daqueles de versões anteriores (que deveriam, se houvesse algum, estarem listados
na seção "Histórico do Documento"). Você pode usar o mesmo título de uma versão anterior se
o editor original daquela versão lhe der permissão;
B. Listar na Página de Título, como autores, uma ou mais das pessoas ou entidades responsá-
veis pela autoria das modificações na Versão Modificada, conjuntamente com pelo menos cinco
dos autores principais do Documento (todos os seus autores principais, se ele tiver menos que
cinco);
C. Colocar na Página de Título o nome do editor da Versão Modificada, como o editor;
D. Preservar todas as notas de copyright do Documento;
E. Adicionar uma nota de copyright apropriada para suas próprias modificações adjacente às
outras notas de copyright;
F. Incluir, imediatamente depois das notas de copyright, uma nota de licença dando ao público
o direito de usar a Versão Modificada sob os termos desta Licença, na forma mostrada no tópico
abaixo;
G. Preservar nessa nota de licença as listas completas das Seções Invariantes e os Textos de
Capa requeridos dados na nota de licença do Documento;
H. Incluir uma cópia inalterada desta Licença;
I. Preservar a seção entitulada "Histórico", e seu título, e adicionar à mesma um item dizendo
pelo menos o título, ano, novos autores e editor da Versão Modificada como dados na Página de
Título. Se não houver uma sessão denominada "Histórico"no Documento, criar uma dizendo o
título, ano, autores, e editor do Documento como dados em sua Página de Título, então adicionar
um item descrevendo a Versão Modificada, tal como descrito na sentença anterior;
J. Preservar o endereço de rede, se algum, dado no Documento para acesso público a uma
cópia Transparente do Documento, e da mesma forma, as localizações de rede dadas no Docu-
mento para as versões anteriores em que ele foi baseado. Elas podem ser colocadas na seção
"Histórico". Você pode omitir uma localização na rede para um trabalho que tenha sido publicado
pelo menos quatro anos antes do Documento, ou se o editor original da versão a que ela se refira
der sua permissão;
K. Em qualquer seção entitulada "Agradecimentos"ou "Dedicatórias", preservar o título da
14
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
seção e preservar a seção em toda substância e fim de cada um dos agradecimentos de contri-
buidores e/ou dedicatórias dados;
L. Preservar todas as Seções Invariantes do Documento, inalteradas em seus textos ou em
seus títulos. Números de seção ou equivalentes não são considerados parte dos títulos da seção;
M. Apagar qualquer seção entitulada "Endossos". Tal sessão não pode ser incluída na Versão
Modificada;
N. Não reentitular qualquer seção existente com o título "Endossos"ou com qualquer outro
título dado a uma Seção Invariante.
Se a Versão Modificada incluir novas seções iniciais ou apêndices que se qualifiquem como
Seções Secundárias e não contenham nenhum material copiado do Documento, você pode optar
por designar alguma ou todas aquelas seções como invariantes. Para fazer isso, adicione seus
títulos à lista de Seções Invariantes na nota de licença da Versão Modificada. Esses títulos preci-
sam ser diferentes de qualquer outro título de seção.
Você pode adicionar uma seção entitulada "Endossos", desde que ela não contenha qual-
quer coisa além de endossos da sua Versão Modificada por várias pessoas ou entidades - por
exemplo, declarações de revisores ou de que o texto foi aprovado por uma organização como a
definição oficial de um padrão.
Você pode adicionar uma passagem de até cinco palavras como um Texto de Capa da Frente
, e uma passagem de até 25 palavras como um Texto de Quarta Capa, ao final da lista de Textos
de Capa na Versão Modificada. Somente uma passagem de Texto da Capa da Frente e uma de
Texto da Quarta Capa podem ser adicionados por (ou por acordos feitos por) qualquer entidade.
Se o Documento já incluir um texto de capa para a mesma capa, adicionado previamente por
você ou por acordo feito com alguma entidade para a qual você esteja agindo, você não pode
adicionar um outro; mas você pode trocar o antigo, com permissão explícita do editor anterior que
adicionou a passagem antiga.
O(s) autor(es) e editor(es) do Documento não dão permissão por esta Licença para que seus
nomes sejam usados para publicidade ou para assegurar ou implicar endossamento de qualquer
Versão Modificada.
COMBINANDO DOCUMENTOS
Você pode combinar o Documento com outros documentos publicados sob esta Licença, sob
os termos definidos na seção 4 acima para versões modificadas, desde que você inclua na com-
binação todas as Seções Invariantes de todos os documentos originais, sem modificações, e liste
todas elas como Seções Invariantes de seu trabalho combinado em sua nota de licença.
O trabalho combinado precisa conter apenas uma cópia desta Licença, e Seções Invariantes
Idênticas com multiplas ocorrências podem ser substituídas por apenas uma cópia. Se houver
múltiplas Seções Invariantes com o mesmo nome mas com conteúdos distintos, faça o título de
15
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
cada seção único adicionando ao final do mesmo, em parênteses, o nome do autor ou editor
origianl daquela seção, se for conhecido, ou um número que seja único. Faça o mesmo ajuste
nos títulos de seção na lista de Seções Invariantes nota de licença do trabalho combinado.
Na combinação, você precisa combinar quaisquer seções entituladas "Histórico"dos diver-
sos documentos originais, formando uma seção entitulada "Histórico"; da mesma forma combine
quaisquer seções entituladas "Agradecimentos", ou "Dedicatórias". Você precisa apagar todas as
seções entituladas como "Endosso".
COLETÂNEAS DE DOCUMENTOS
Você pode fazer uma coletânea consitindo do Documento e outros documentos publicados
sob esta Licença, e substituir as cópias individuais desta Licença nos vários documentos com
uma única cópia incluida na coletânea, desde que você siga as regras desta Licença para cópia
exata de cada um dos Documentos em todos os outros aspectos.
Você pode extrair um único documento de tal coletânea, e distribuí-lo individualmente sob
esta Licença, desde que você insira uma cópia desta Licença no documento extraído, e siga esta
Licença em todos os outros aspectos relacionados à cópia exata daquele documento.
AGREGAÇÃO COM TRABALHOS INDEPENDENTES
Uma compilação do Documento ou derivados dele com outros trabalhos ou documentos se-
parados e independentes, em um volume ou mídia de distribuição, não conta como uma Ver-
são Modificada do Documento, desde que nenhum copyright de compilação seja reclamado pela
compilação. Tal compilação é chamada um "agregado", e esta Licença não se aplica aos outros
trabalhos auto-contidos compilados junto com o Documento, só por conta de terem sido assim
compilados, e eles não são trabalhos derivados do Documento.
Se o requerido para o Texto de Capa na seção 3 for aplicável a essas cópias do Documento,
então, se o Documento constituir menos de um quarto de todo o agregado, os Textos de Capa
do Documento podem ser colocados em capas adjacentes ao Documento dentro do agregado.
Senão eles precisarão aparecer nas capas de todo o agregado.
TRADUÇÃO
Tradução é considerada como um tipo de modificação, então você pode distribuir traduções
do Documento sob os termos da seção 4. A substituição de Seções Invariantes por traduções
requer uma permissão especial dos detentores do copyright das mesmas, mas você pode incluir
traduções de algumas ou de todas as Seções Invariantes em adição às versões orignais dessas
Seções Invariantes. Você pode incluir uma tradução desta Licença desde que você também in-
clua a versão original em Inglês desta Licença. No caso de discordância entre a tradução e a
16
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
versão original em Inglês desta Licença, a versão original em Inglês prevalecerá.
TÉRMINO
Você não pode copiar, modificar, sublicenciar, ou distribuir o Documento exceto como expres-
samente especificado sob esta Licença. Qualquer outra tentativa de copiar, modificar, sublicen-
ciar, ou distribuir o Documento é nula, e resultará automaticamente no término de seus direitos
sob esta Licença. Entretanto, terceiros que tenham recebido cópias, ou direitos de você sob esta
Licença não terão suas licenças terminadas, tanto quanto esses terceiros permaneçam em total
acordo com esta Licença.
REVISÕES FUTURAS DESTA LICENÇA
A Free Software Foundation pode publicar novas versões revisadas da Licença de Documen-
tação Livre GNU de tempos em tempos. Tais novas versões serão similares em espirito à versão
presente, mas podem diferir em detalhes ao abordarem novos porblemas e preocupações. Veja
http://www.gnu.org/copyleft/.
A cada versão da Licença é dado um número de versão distinto. Se o Documento especificar
que uma versão particular desta Licença "ou qualquer versão posterior"se aplica ao mesmo, você
tem a opção de seguir os termos e condições daquela versão específica, ou de qualquer versão
posterior que tenha sido publicada (não como rascunho) pela Free Software Foundation. Se o
Documento não especificar um número de Versão desta Licença, você pode escolher qualquer
versão já publicada (não como rascunho) pela Free Software Foundation.
ADENDO: Como usar esta Licença para seus documentos
Para usar esta Licença num documento que você escreveu, inclua uma cópia desta Licença
no documento e ponha as seguintes notas de copyright e licenças logo após a página de título:
Copyright (c) ANO SEU NOME.
É dada permissão para copiar, distribuir e/ou modificar este documento sob os termos da Licença
de Documentação Livre GNU, Versão 1.1 ou qualquer versão posterior publicada pela Free Soft-
ware Foundation; com as Seções Invariantes sendo LISTE SEUS TÍTULOS, com os Textos da
Capa da Frente sendo LISTE, e com os Textos da Quarta-Capa sendo LISTE. Uma cópia da li-
cença está inclusa na seção entitulada "Licença de Documentação Livre GNU".
Se você não tiver nenhuma Seção Invariante, escreva "sem Seções Invariantes"ao invés de
dizer quais são invariantes. Se você não tiver Textos de Capa da Frente, escreva "sem Textos de
Capa da Frente"ao invés de "com os Textos de Capa da Frente sendo LISTE"; o mesmo para os
Textos da Quarta Capa.
Se o seu documento contiver exemplos não triviais de código de programas, nós recomenda-
mos a publicação desses exemplos em paralelo sob a sua escolha de licença de software livre,
17
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
tal como a GNU General Public License, para permitir o seu uso em software livre.
18
Parte IV
Ruby on Rails
19
Capítulo 1
O que é o curso Ruby on Rails
Ruby on Rails, ou simplismente Rails, é um framework para aplicações web desenvolvido
todo na linguagem de programação Ruby. Para vocês, que estão fazendo esse curso, devem está
familiarizados com essa linguagem de programação.
Rails é uma ferramenta muito poderosa na hora de fazer aplicações web, como vocês poderão
ver ao longo do curso.
20
Capítulo 2
Plano de ensino
2.1 Objetivo
Qualificar técnicos e programadores no framework Ruby on Rails
2.2 Público Alvo
Técnicos e Programadores que desejam trabalhar com Ruby on Rails.
2.3 Pré-requisitos
Os usuários deverão ser, necessariamente, indicados por empresas públicas e ter conheci-
mento básico acerca da lógica de programação, HTML, Linguagem Ruby, MySQL e CSS.
2.4 Descrição
O curso de Ruby on Rails será realizado na modalidade EAD e utilizará a plataforma Moodle
como ferramenta de aprendizagem. Ele é composto de um módulo de aprendizado que será dado
na primeira semana e um módulo de avaliação que será dado na segunda semana. O material
didático estará disponível on-line de acordo com as datas pré-estabelecidas no calendário. A
versão utilizada para o Ruby on Rails será a 1.1.
2.5 Metodologia
O curso está dividido da seguinte maneira:
2.6 Cronograma
• Lição 1 - Iniciando o Ruby on Rails;
• Lição 2 - Gerando migrações e modelos de dados;
21
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
• Lição 3 - MVC e CONTROLLER;
• Lição 4 - Layouts e Roteamento;
• Lição 5 - Scaffolding e Validações;
• Lição 6 - Segundo controller;
• Lição 7 - Extendendo um modelo de dados e Helpers.
• Lição 8 - Relacionamentos;
• Lição 9 - Belongs to
• Lição 10 - has many, has one, e has many, through
As lições contém o contéudo principal. Elas poderão ser acessadas quantas vezes forem neces-
sárias, desde que esteja dentro da semana programada. Ao final de uma lição, você receberá
uma nota de acordo com o seu desempenho. Responda com atenção às perguntas de cada lição,
pois elas serão consideradas na sua nota final. Caso sua nota numa determinada lição for menor
do que 6.0, sugerimos que você faça novamente esta lição.
Ao final do curso será disponibilizada a avaliação referente ao curso. Tanto as notas das lições
quanto a da avaliação serão consideradas para a nota final. Todos os módulos ficarão visíveis
para que possam ser consultados durante a avaliação final.
Aconselhamos a leitura da "Ambientação do Moodle"para que você conheça a plataforma de
Ensino a Distância, evitando dificuldades advindas do "desconhecimento"sobre a mesma.
Os instrutores estarão a sua disposição ao longo de todo curso. Qualquer dúvida deverá ser
enviada no fórum. Diariamente os monitores darão respostas e esclarecimentos.
2.7 Programa
O curso Ruby on Rails oferecerá o seguinte conteúdo:
• Iniciando o Ruby on Rails;
• Gerando migrações e modelos de dados;
• MVC e CONTROLLER;
• Layouts e Roteamento;
• Scaffolding e Validações;
• Segundo controller;
• Extendendo um modelo de dados e Helpers.
• Relacionamentos;
• Belongs to
• has many, has one, e has many, through
22
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
2.8 Avaliação
Toda a avaliação será feita on-line.
Aspectos a serem considerados na avaliação:
• Iniciativa e autonomia no processo de aprendizagem e de produção de conhecimento;
• Capacidade de pesquisa e abordagem criativa na solução dos problemas apresentados.
Instrumentos de avaliação:
• Participação ativa nas atividades programadas.
• Avaliação ao final do curso.
• O participante fará várias avaliações referente ao conteúdo do curso. Para a aprovação e
obtenção do certificado o participante deverá obter nota final maior ou igual a 6.0 de acordo
com a fórmula abaixo:
• Nota Final = ((ML x 7) + (AF x 3)) / 10 = Média aritmética das lições
• AF = Avaliações
2.9 Bibliografia
• Site oficial: http://www.rubyonrails.org;
• Rails para sua diversão e lucro.
• http://forum.rubyonbr.org/forums/4/topics/2503
23
Capítulo 3
Iniciando o Ruby on Rails
Essa lição tem uma parte introdutória ao Rails e a instalação do mesmo.
3.1 Introdução
Ruby on Rails é um poderoso Framework para aplicações web. O curso é voltado para desen-
volvedores já familiarizados com algum ambiente de desenvolvimento Web, seja usando Linux ou
Windows. Por razões de tempo, o curso assume que o desenvolvedor já tenha conhecimento de
pelo menos uma linguagem de programação, de um banco de dados relacional qualquer e que
seja capaz de estabelecer um ambiente para essa linguagem e banco de dados em sua plata-
forma de escolha, ou seja, que tenha o conhecimento técnico para acompanhar os passos dados
no curso sem maiores problemas. O curso não assume, porém, que o desenvolvedor saiba fazer
o mesmo para o Rails e explica isso nos detalhes necessários.
Um certo conhecimento do Ruby é requerido, embora a linguagem seja simples e poderosa
o suficiente para ser inteligível para qualquer desenvolvedor com uma experiência razoável em
outra linguagem de alto nível. Apesar disso, esse tutorial pode não ser tão fácil para desenvolve-
dores que estejam dando os seus primeiros passos em programação e em especial programação
para a Web?embora eu acredite que desenvolvedores iniciantes possam se beneficiar muito com
o contato com uma linguagem mais poderosa e com um framework mais elaborado.
Foi usado nesse curso o MySQL na elaboração do tutorial por ele ser um banco de fácil insta-
lação, mas você pode usar o que mais se adaptar ao seu ambiente, principalmente, considerando
que o Rails esconde a maior parte da complexidade nessa área e que ele suporta os principais
bancos de dados existentes no mercado. Para começar, vamos assumir que você tenha um
banco de dados instalado e que esteja pronto para instalar o Rails e quaisquer outras bibliotecas
necessárias.
Como é bom que você já tenha se familiarizado com a linguagem Ruby (seria útil que você já
tenha feito o nosso curso Linguagem Ruby), a de se supor que você já tenha instalado em sua
máquina o Ruby.
O Ruby é uma linguagem de alto nível, tão completa quanto uma linguagem poderia ser. Sua
sintaxe é bem simples, e lembra Ada e Eiffel, com algumas pitadas de Perl em alguns pontos.
3.2 Instalação
Para verificar a versão instalada do Ruby, use o seguinte comando:
24
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
ronaldo@minerva: $ ruby -v ruby 1.8.4 (2005-12-24) [i486-linux]
Uma vez que o Ruby esteja instalado, é hora de fazer o mesmo com o Rails. O procedimento
é bem simples:
Como usuário root digite: apt-get install rails
Simples assim.
Novas versões do Rails são instalados por um processo similar. Se você já baixou alguma
versão alguma vez, use o mesmo comando acima para atualizar a sua distribuição para a versão
mais recente, lembrando, principalmente, de que a versão 1.1.6 corrige um sério problema de
segurança nas versões anteriores e
deve ser a única usada em um servidor público. Com os passos acima finalizados e um banco
de dados disponível, você está pronto para começar o desenvolvimento em Rails.
A primeira coisa a fazer, então, é criar o diretório de trabalho da aplicação. Isso é feito com o
comando abaixo:
ronaldo@minerva: /tmp$ rails gtd
create
create app/controllers
create app/helpers
create app/models
create app/views/layouts
create config/environments
create components
create db
create doc
create lib
create lib/tasks
create log
create public/images
create public/javascripts
create public/stylesheets
create script/performance
create script/process
create test/fixtures
create test/functional
create test/integration
create test/mocks/development
create test/mocks/test
create test/unit
create vendor
create vendor/plugins
...
O comando rails gera o esqueleto completo de uma aplicação, pronta para rodar. Esse co-
mando foi criado em seu sistema quando você instalou as bibliotecas necessárias.
No esqueleto gerado, cada parte da aplicação tem um local específico para ser colocado.
Isso deriva de uma das filosofias por trás do Rails que pode ser descrita pela frase ?convenção
ao invés de configuração?. Convenção, nesse caso, significa que há um acordo entre o framework
e você, o desenvolvedor, de modo que você não precisa de preocupar com certos detalhes que,
de outra forma, teriam que se descritos em um arquivo de configuração.
25
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
No Rails, basta executar uma determinada ação ou criar um determinado arquivo e as coi-
sas funcionarão da maneira que você deseja e espera automaticamente, sem necessidade de
qualquer trabalho adicional. A princípio isso pode parecer um pouco restritivo, mas na prática
funciona perfeitamente. E sendo extremamente flexível, o Rails permite que você mude qualquer
coisa que precise, quando precisar.
Agora que temos uma aplicação básica, vamos rodá-la e ver o resultado.
Uma das vantagens do Rails é que o ciclo de codificar-rodar-e-testar é bem rápido. Basta fazer
uma alteração para ver imediatamente o resultado, sem a necessidade de recarregar processos,
esperar a compilação da aplicação ou enviá-la para um servidor especialmente preparado. O
máximo que você terá
que fazer no Rails é reiniciar o servidor Web no caso de alguma mudança fundamental na
configuração básica da aplicação, algo que ocorre com pouca freqüência.
Para facilitar a vida, o Rails vem com seu próprio servidor Web, utilizando as bibliotecas do
próprio Ruby. Para rodar o servidor, basta usar um dos scripts utilitários presentes em cada
aplicação gerada pelo Rails (veja o diretório script sob o esqueleto da aplicação).
O comando, executado dentro do diretório da aplicação, é o seguinte:
ronaldo@minerva: /tmp/gtd$ script/server
=> Booting WEBrick...
=> Rails application started on http://0.0.0.0:3000
style="text-align: justify; font-family: courier new,courier,monospace; font-weight: bold;»=>
Ctrl-C to shutdown server; call with –help for options
[2006-09-20 10:31:40] INFO WEBrick 1.3.1
[2006-09-20 10:31:40] INFO ruby 1.8.4 (2005-12-24) [i486-linux]
[2006-09-20 10:31:40] INFO WEBrick::HTTPServer#start: pid=8262 port=3000
Como você poder ver, o comando inicia uma instância do servidor WEBrick, capaz de servir
aplicações Rails sem necessidade de qualquer configuração adicional. O servidor roda local-
mente e recebe requisições na porta 3000. Sendo um servidor simples e embutido, o WEBrick
não é capaz de receber requisições
simultâneas, mas permite que testemos perfeitamente a nossa aplicação. Acessando o ende-
reço da aplicação você tem o seguinte:
26
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 1
Como mostrado acima, temos uma aplicação inicial rodando que, inclusive, mostra quais são
os próximos passos para continuar o desenvolvimento da mesma.
3.3 Configurando Banco de Dados
Vamos acatar a sugestão da página inicial e criar e configurar o banco de dados da aplica-
ção. Esse primeiro passo é muito importante porque o Rails usa as informações proveniente
do schema do banco de dados para gerar automaticamente arquivos e configurações adicionais.
Esse é mais um exemplo de convenção ao invés de configuração. Dessa forma, garantir que o
banco está funcionando corretamente, configurado para uso da aplicação, é o passo inicial de
qualquer desenvolvimento em Rails.
O arquivo de configuração de banco de dados se chamada database.yml e está localizado no
diretório config, junto com os demais arquivos de configuração da aplicação.
Esse arquivo, removendo os comentários (as linhas iniciadas com #), tem o seguinte formato
Ú ÐÓÔÑ ÒØ
ÔØ Ö ÑÝ×ÕÐ
27
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ø × Ø Ú ÐÓÔÑ ÒØ
Ù× ÖÒ Ñ ÖÓÓØ
Ô ××ÛÓÖ
Óר ÐÓ
 Ð Óר
Ø ×Ø
ÔØ Ö ÑÝ×ÕÐ
Ø × Ø Ø ×Ø
Ù× ÖÒ Ñ ÖÓÓØ
Ô ××ÛÓÖ
Óר ÐÓ
 Ð Óר
ÔÖÓ Ù
Ø ÓÒ
ÔØ Ö ÑÝ×ÕÐ
Ø × Ø ÔÖÓ Ù
Ø ÓÒ
Ù× ÖÒ Ñ ÖÓÓØ
Ô ××ÛÓÖ
Óר ÐÓ
 Ð Óר
A extensao .yml se refere ao formato do arquivo, que utiliza uma linguagem de domínio cha-
mada YAML. Por hora, basta saber que é uma linguagem de serialização de dados favorecida por
desenvolvedores Ruby e Rails.
Uma aplicação Rails geralmente utiliza três bancos de dados, como demonstrado acima, um
para cada ambiente de desenvolvimento padrão. Um banco de dados é utilizado para o desen-
volvimento, onde todas as mudanças são aplicadas. Esse banco tem seu correspondente em
um banco de produção, onde modificações somente são aplicadas uma vez que estejam comple-
tas. O arquivo permite configurar, inclusive, um banco remoto para onde suas modificações finais
serão redirecionadas?embora geralmente seja melhor utilizar um outro método de implantação,
como veremos mais adiante. O terceiro banco mostrado acima é um banco de testes, utilizado
pelo Rails para a execução de unit testing. Esse banco deve ser mantido necessariamente à
parte já que todos os dados e tabelas presentes no mesmo são excluídos e recriados a cada
teste completo efetuado na aplicação.
Vamos criar o banco agora:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ÑÝ×ÕÐ ¹Ù ÖÓÓØ ¹Ô
ÒØ Ö Ô ××ÛÓÖ
Ï Ð
ÓÑ ØÓ Ø ÅÝËÉÄ ÑÓÒ ØÓÖº ÓÑÑ Ò × Ò Û Ø ÓÖ º
ÓÙÖ ÅÝËÉÄ 
ÓÒÒ 
Ø ÓÒ × ØÓ × ÖÚ Ö Ú Ö× ÓÒ º¼º¾¾¹ Ò ¼Ù ÙÒØÙ º¼ º¾¹ÐÓ
ÌÝÔ ³ ÐÔ ³ ÓÖ ³ ³ ÓÖ ÐÔº ÌÝÔ ³
³ ØÓ 
Ð Ö Ø Ù Öº
ÑÝ×ÕÐ 
Ö Ø Ø × Ø
ÉÙ ÖÝ Çø ½ ÖÓÛ 
Ø ´¼º × 
µ
ÑÝ×ÕÐ 
Ö Ø Ø × Ø Ø ×Ø
ÉÙ ÖÝ Çø ½ ÖÓÛ 
Ø ´¼º ¿ × 
µ
ÑÝ×ÕÐ Ù× Ø
Ø × 
 Ò
ÑÝ×ÕÐ
Modificando o arquivo de configuração para desenvolvimento local (database.yml), teríamos
algo assim:
28
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ú ÐÓÔÑ ÒØ
ÔØ Ö ÑÝ×ÕÐ
Ø × Ø
Ù× ÖÒ Ñ ÖÓÓØ
Ô ××ÛÓÖ
Óר ÐÓ
 Ð Óר
×Ó
 Ø »Ú Ö»ÖÙÒ»ÑÝ×ÕÐ »ÑÝ×ÕÐ º×Ó
Ø ×Ø
ÔØ Ö ÑÝ×ÕÐ
Ø × Ø Ø ×Ø
Ù× ÖÒ Ñ ÖÓÓØ
Ô ××ÛÓÖ
Óר ÐÓ
 Ð Óר
×Ó
 Ø »Ú Ö»ÖÙÒ»ÑÝ×ÕÐ »ÑÝ×ÕÐ º×Ó
ÔÖÓ Ù
Ø ÓÒ
Ú ÐÓÔÑ ÒØ
No caso acima, eu configurei os banco de produção e desenvolvimento para apontarem para
o mesmo local já que o desenvolvimento está limitado à minha máquina. Essa é uma estratégia
interessante a usar quando queremos testar uma aplicação nas duas situações localmente sem
nos preocuparmos em copiar o banco a todo momento?mesmo que o Rails permita isso com
pouco mais do que alguns comandos. Eu precisei também acrescentar o método de transporte
socket à configuração já que em minha máquina, especificamente, o MySQL não permite cone-
xões de rede em sua configuração padrão. Outros tipos bancos de dados são configurados de
maneira similar, mudando o parâmetro adapter e quaisquer outras configurações necessárias.
Uma maneira mais simples de gerar uma arquivo de configuração específico para o banco de da-
dos que você está usando é já invocar o comando para gerar o esqueleto da aplicação passando
um parâmetro para isso. Por exemplo:
rails –database=oracle gtd
O comando acima gera o mesmo esqueleto da aplicação, com a única diferença de que o
arquivo database.yml será um pouco diferente para levar em conta as diferenças do Oracle. Vol-
tando à nossa aplicação, como um arquivo de configuração importante foi mudado, o servidor
Web precisa ser reiniciado. Isso acontece porque ele somente lê essas configurações no início
de execução. Esse é um dos raros casos em que um servidor de desenvolvimento precisa ser
reiniciado já que o Rails recarrega praticamente qualquer modificação feita na aplicação quando
está no modo de desenvolvimento.
Agora temos uma aplicação e um banco de dados configurado. Com isso já podemos iniciar
o processo de desenvolvimento propriamente dito.
Para acesso ao banco de dados, o Rails usa classes de dados conhecidas como models, ou
modelos de dados. Essas classes mascaram os detalhes ¨sórdidos¨do acesso ao banco de dados
providenciando uma interface fácil e intuitiva ao desenvolvedor. Em qualquer aplicação, teremos
pelo menos um modelo de dados para utilizar na mesma. E a maneira mais fácil de fazer isso é
criar automaticamente a tabela no banco de dados, utilizando um dos scripts do Rails.
O Rails automaticamente entende que todas as tabelas criadas no banco para uso em mode-
los, ou classes de dados, satisfarão a duas condições: terão um nome plural em inglês e terão
29
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
uma chave primária surrogada inteira e auto-incrementada chamada id. É possível mudar ambas
as condições, mas inicialmente ficaremos com elas para não ter que modificar o que o Rails gera
e usa automaticamente.
Para facilitar o desenvolvimento, a aplicação desenvolvida está em inglês, que espero seja
simples o suficiente mesmo para a compreensão do leitor que não domine plenamente este idi-
oma. Considerando a profusão de termos em inglês em nossa área acho que isso não será um
problema. O uso do inglês evita que tenhamos que pensar em alguns detalhes de tradução e
globalização enquanto estamos aprendendo o Rails. Mais no fim do tutorial explicaremos como
mudar algumas das coisas que o Rails por como padrão.
30
Capítulo 4
Gerando Migrações e Modelos de
Dados
Essa lição tem como objetivo mostrar como alterar qualquer natureza no banco de dados.
4.1 Gerando Migrações e Modelos de dados I
Para manter portabilidade e facilitar o controle de versionamento do banco de dados, o Rails
utiliza algo chamado migrations (migrações). São scripts em Ruby descrevendo modificações de
qualquer natureza no banco de dados. Migrações são a maneira mais fácil de acrescentar tabelas
e classes de dados ao Rails e é o que utilizaremos agora. A primeira tabela que vamos criar será
a tabela de contextos. Contextos, no GTD, são, basicamente, os ambientes onde uma ação será
executada, como, por exemplo, casa, escritório, e-mail, telefone, etc. Vamos gerar então uma
migração para essa primeira modificação no banco:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ» Ò Ö Ø Ñ Ö Ø ÓÒ 
Ö Ø 
ÓÒØ ÜØ×

Ö Ø »Ñ Ö Ø

Ö Ø »Ñ Ö Ø »¼¼½ 
Ö Ø 
ÓÒØ ÜØ×ºÖ
O script generate é uma das ferramentas cruciais do Rails que utilizaremos ao longo de todo
nosso curso, sendo usado, como o nome indica, para criar basicamente qualquer estrutura que
precisamos em uma aplicação. O seu primeiro parâmetro é o tipo de objeto que estamos ge-
rando, seu segundo parâmetro é o nome desse objeto e quaisquer outros parâmetro adicionais
indicam opções de geração. No caso acima, estamos gerando uma migração, cujo nome é cre-
ate_contexts.
No Rails, existem muitas convenções quanto ao uso de nomes, que são seguidas pelos
comandos do mesmo, com conversões automáticas quando necessário. No caso acima, por
exemplo, o nome que usamos será automaticamente convertido em um nome de classe, que
no Ruby são expressas com capitalização alternada, como você poderá ver abaixo. O resultado
do comando é um arquivo novo, prefixado pela versão da migração, que foi criado no diretório
db/migrate. Esse prefixo é usado para controlar quais alterações um banco precisa sofrer para
chegar a uma versão específica. Editando o arquivo, temos o seguinte:

Ð ×× Ö Ø ÓÒØ ÜØ× 
Ø Ú Ê 
ÓÖ Å Ö Ø ÓÒ
× Ð ºÙÔ
31
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ò
× Ð º ÓÛÒ
Ò
Ò
O Rails criou uma classe derivada () da classe ActiveRecord::Migration com dois métodos.
Esses métodos, por estarem prefixados por self, indicam no Ruby que os mesmos podem ser
chamados diretamente na classe (métodos estáticos na terminologia do C++, C# e do Java), sem
necessidade de uma instância. O método self.up é utilizado para efetuar as modificações. O
seu oposto, self.down, é usado para desfazer essas modificações caso você esteja revertendo
para uma versão anterior do banco. Dependendo da forma como os métodos forem escritos, eles
serão realmente complementares. Obviamente é possível que modificações sejam efetuadas que
não são reversíveis. Nesse caso, o Rails emitirá um erro se uma migração para uma versão mais
baixa for tentada. Vamos editar o arquivo agora para incluir a tabela que desejamos criar:

Ð ×× Ö Ø ÓÒØ ÜØ× 
Ø Ú Ê 
ÓÖ Å Ö Ø ÓÒ
× Ð ºÙÔ

Ö Ø Ø Ð 
ÓÒØ ÜØ× Ó Ø
غ
ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò
Ò
Ò
× Ð º ÓÛÒ
ÖÓÔ Ø Ð 
ÓÒØ ÜØ×
Ò
Ò
Para efetuar suas migrações, o Rails utiliza uma linguagem de domínio que permite especificar
operações de banco de dados de forma abstrata, que não está presa a um servidor específico.
É possível executar operações diretamente via SQL no banco, mas isso não é recomendado por
quebrar essa abstração.
No caso acima, o método create_table dentro de self.up serve para especificar a tabela que
será criada. Esse método recebe um bloco como parâmetro (indicado pela palavra-chave do) que
especifica as colunas que serão adicionadas.
Blocos são uma das partes mais interessantes do Ruby e vale a estudar um pouco o que eles
podem fazer já que o uso dos mesmos é extenso em qualquer aplicação na linguagem, incluindo o
Rails. No Ruby, os blocos são valores de primeira classe, que pode ser atribuídos e manipulados
como qualquer outro objeto.
Um outro detalhe a manter em mente é o uso extensivo de símbolos no Ruby. No caso acima,
o próprio nome da tabela é denotado por um símbolo. Símbolos são similares a strings, com a
diferença fundamental que são internalizados e existem com uma única instância que permite um
uso transparente e eficiente dos mesmos.
Voltando ao nosso código, como a tabela terá somente uma coluna inicialmente, que é o nome
do contexto, somente precisamos de uma linha, identificando o nome da coluna e seu tipo. Mais à
frente veremos outros tipos e opções. O método self.down, como explicando, realiza a operação
inversa destruindo a tabela.
Agora é hora de aplicar essa migração ao banco, subindo sua versão. Para isso, temos o
utilitário rake, que é parte do Ruby. O rake é o equivalente Ruby do make, sendo capaz de realizar
tarefas descritas em um Rakefile, da mesma forma que o make faz uso de um Makefile. O Rails
32
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
vem com seu próprio Rakefile que permite a execução de várias de suas tarefas necessárias,
incluindo db:migrate, que aplica as migrações ainda não efetuadas a um banco. Rodamos o
comando da seguinte forma:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° Ö Ñ Ö Ø
´ Ò »ØÑÔ» Ø µ
Ö Ø ÓÒØ ÜØ× Ñ Ö Ø Ò
¹¹ 
Ö Ø Ø Ð ´ 
ÓÒØ ܨ׵
¹ ½º¾¼ ×
Ö Ø ÓÒØ ÜØ× Ñ Ö Ø ´½º¾¼ ¾×µ
Se observamos o banco agora, teremos o seguinte schema:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ÑÝ×ÕÐ ¹Ù ÖÓÓØ ¹Ô Ø
ÑÝ×ÕÐ × ÓÛ Ø Ð ×
·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·
Ì Ð × Ò Ø
·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·

ÓÒØ ÜØ×
×
 Ñ Ò Ó
·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·
¾ ÖÓÛ× Ò × Ø ´¼º¼¼ × 
µ
Duas tabelas foram criadas, contexts e schema_info. A primeira é a que especificamos. A
segunda descreve informações do banco para o Rails, para controlar o versionamento do mesmo.
A tabela contexts ficou assim:
Ó ÒÚÑ »ØÑÔ» Ø ° ÑÝ×ÕÐ ¹Ù ÖÓÓØ ¹Ô
ÑÝ×ÕÐ ×
Ö 
ÓÒØ ÜØ×
·¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·
Ð ÌÝÔ ÆÙÐÐ Ã Ý ÙÐØ ÜØÖ
·¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·
ÒØ´½½µ ÆÇ ÈÊÁ ÆÍÄÄ ÙØÓ Ò
Ö Ñ ÒØ
Ò Ñ Ú Ö
 Ö´¾ µ Ë ÆÍÄÄ
·¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·
¾ ÖÓÛ× Ò × Ø ´¼º¼¼ × 
µ
Como você pode ver, não é preciso especificar a chave primária surrogada, que é automati-
camente criada pelo Rails. A tabela schema_info possui os seguintes dados:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ÑÝ×ÕÐ ¹Ù ÖÓÓØ ¹Ô Ø
ÑÝ×ÕÐ × Ð 
Ø ¶ ÖÓÑ ×
 Ñ Ò Ó
·¹¹¹¹¹¹¹¹¹·
Ú Ö× ÓÒ
·¹¹¹¹¹¹¹¹¹·
½
·¹¹¹¹¹¹¹¹¹·
½ ÖÓÛ Ò × Ø ´¼º¼¼ × 
µ
33
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Esse número de versão será incrementado ou decrementado dependendo da direção da mi-
gração.
A migração também criou o arquivo db/schema.rb, contendo uma representação do banco em
Ruby, que pode ser usada para recriar a estrutura do mesmo em qualquer banco suportado pelo
Rails, usando uma outra tarefa do rake.
O arquivo é auto-gerado e não deve ser modificado manualmente. Seu formato pode ser visto
abaixo:
Ì × Ð × ÙØÓ Ò Ö Ø º ÁÒר Ó Ø Ò Ø × Ð ¸ ÔÐ × Ù× Ø
Ñ Ö Ø ÓÒ× ØÙÖ Ó 
Ø Ú Ê 
ÓÖ ØÓ Ò
Ö Ñ ÒØ ÐÐÝ ÑÓ Ý ÝÓÙÖ Ø × ¸ Ò
Ø Ò Ö Ò Ö Ø Ø × ×
 Ñ Ò Ø ÓÒº

Ø Ú Ê 
ÓÖ Ë
 Ñ º Ò ´ Ú Ö× ÓÒ ½µ Ó

Ö Ø Ø Ð 
ÓÒØ ÜØ× ¸ ÓÖ
 ØÖÙ Ó Ø
غ
ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò
Ò
Ò
Note apenas que essa representação é limitada às tabelas em si e não inclui chaves es-
trangeiras, triggers ou stored procedures. O próximo passo agora é criar a classe de dados
correspondente à tabela. Para isso, usamos o comando abaixo:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ» Ò Ö Ø ÑÓ Ð 
ÓÒØ ÜØ
Ü ×Ø× ÔÔ»ÑÓ Ð×»
Ü ×Ø× Ø ×Ø»ÙÒ Ø»
Ü ×Ø× Ø ×Ø» ÜØÙÖ ×»

Ö Ø ÔÔ»ÑÓ Ð×»
ÓÒØ ÜØºÖ

Ö Ø Ø ×Ø»ÙÒ Ø»
ÓÒØ ÜØ Ø ×ØºÖ

Ö Ø Ø ×Ø» ÜØÙÖ ×»
ÓÒØ ÜØ×ºÝÑÐ
Ü ×Ø× »Ñ Ö Ø
ÒÓØ Ö Ñ Ö Ø ÓÒ × ÐÖ Ý Ò Ñ 
Ö Ø 
ÓÒØ ÜØ× »Ñ Ö Ø »¼¼½ 
Ö Ø 
ÓÒØ ÜØ×ºÖ
O Rails utiliza uma estratégia de desenvolvimento (conhecidas como patterns de maneira
geral) chamada de MVC (Model-View-Controller). Essa estratégia separa os componentes da
aplicação em partes distintas que não só facilitam o desenvolvimento como também facilitam a
manutenção. O que estamos vendo no momento são os models, que correspondem à camada de
acesso ao banco de dados, implementada no Rails por um componente denominado ActiveRe-
cord. O comando acima gera toda estrutura de suporte ao modelo, incluindo testes e migrações
para o mesmo. Como geramos a nossa migração inicial manualmente, o Rails nos informa que
já existe uma com o mesmo nome que ele pretendia gerar e que ele está pulando esse passo.
O arquivo responsável pela implementação do modelo está em app/model/context.rb e contém
apenas o seguinte:

Ð ×× ÓÒØ ÜØ 
Ø Ú Ê 
ÓÖ ×
Ò
Essas duas linhas, apoiadas pelo Rails, já providenciam uma riqueza de implementação que
nos permite recuperar, inserir e atualizar dados no banco, e executar uma série de outras opera-
ções complexas sem a necessidade de qualquer comando SQL direto.
Vamos criar agora um novo modelo correspondendo à tabela de projetos. Vamos deixar que
o Rails gere a migração dessa vez. O comando é:
34
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ» Ò Ö Ø ÑÓ Ð ÔÖÓ 
Ø
Ü ×Ø× ÔÔ»ÑÓ Ð×»
Ü ×Ø× Ø ×Ø»ÙÒ Ø»
Ü ×Ø× Ø ×Ø» ÜØÙÖ ×»

Ö Ø ÔÔ»ÑÓ Ð×»ÔÖÓ 
غÖ

Ö Ø Ø ×Ø»ÙÒ Ø»ÔÖÓ 
Ø Ø ×ØºÖ

Ö Ø Ø ×Ø» ÜØÙÖ ×»ÔÖÓ 
Ø×ºÝÑÐ
Ü ×Ø× »Ñ Ö Ø

Ö Ø »Ñ Ö Ø »¼¼¾ 
Ö Ø ÔÖÓ 
Ø×ºÖ
Você pode ver que o Rails gerou um template da migração, e basta editá-la:

Ð ×× Ö Ø ÈÖÓ 
Ø× 
Ø Ú Ê 
ÓÖ Å Ö Ø ÓÒ
× Ð ºÙÔ

Ö Ø Ø Ð ÔÖÓ 
Ø× Ó Ø
غ
ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò
Ò
Ò
× Ð º ÓÛÒ
ÖÓÔ Ø Ð ÔÖÓ 
Ø×
Ò
Ò
O arquivo final seria, com base no que pensamos até o momento:

Ð ×× Ö Ø ÈÖÓ 
Ø× 
Ø Ú Ê 
ÓÖ Å Ö Ø ÓÒ
× Ð ºÙÔ

Ö Ø Ø Ð ÔÖÓ 
Ø× Ó Ø
غ
ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò
غ
ÓÐÙÑÒ ×
Ö ÔØ ÓÒ¸ Ø ÜØ
Ò
Ò
× Ð º ÓÛÒ
ÖÓÔ Ø Ð ÔÖÓ 
Ø×
Ò
Ò
Você não precisa se preocupar em criar todos os campos inicialmente. Você pode sempre
usar outra migração para isso. Rodando o comando rake para carregar as migrações mais uma
vez, temos o seguinte:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° Ö Ñ Ö Ø
´ Ò » ÓÑ »ÖÓÒ Ð Ó»ØÑÔ» Ø µ
Ö Ø ÈÖÓ 
Ø× Ñ Ö Ø Ò
¹¹ 
Ö Ø Ø Ð ´ ÔÖÓ 
Ø×µ
¹ ¼º½ ¿×
Ö Ø ÈÖÓ 
Ø× Ñ Ö Ø ´¼º½ ×µ
O resultado final do banco seria:
35
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ÑÝ×ÕÐ ¹Ù ÖÓÓØ ¹Ô Ø
ÑÝ×ÕÐ × ÓÛ Ø Ð ×
·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·
Ì Ð × Ò Ø
·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·

ÓÒØ ÜØ×
ÔÖÓ 
Ø×
×
 Ñ Ò Ó
·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·
¿ ÖÓÛ× Ò × Ø ´¼º¼¼ × 
µ
ÑÝ×ÕÐ ×
Ö ÔÖÓ 
Ø×
·¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·
Ð ÌÝÔ ÆÙÐÐ Ã Ý ÙÐØ ÜØÖ
·¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·
ÒØ´½½µ ÆÇ ÈÊÁ ÆÍÄÄ ÙØÓ Ò
Ö Ñ ÒØ
Ò Ñ Ú Ö
 Ö´¾ µ Ë ÆÍÄÄ
×
Ö ÔØ ÓÒ Ø ÜØ Ë ÆÍÄÄ
·¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·
¿ ÖÓÛ× Ò × Ø ´¼º¼¼ × 
µ
ÑÝ×ÕÐ × Ð 
Ø ¶ ÖÓÑ ×
 Ñ Ò Ó
·¹¹¹¹¹¹¹¹¹·
Ú Ö× ÓÒ
·¹¹¹¹¹¹¹¹¹·
¾
·¹¹¹¹¹¹¹¹¹·
½ ÖÓÛ Ò × Ø ´¼º¼¼ × 
µ
E o arquivo db/schema.rb agora contém:
Ì × Ð × ÙØÓ Ò Ö Ø º ÁÒר Ó Ø Ò Ø × Ð ¸ ÔÐ × Ù× Ø
Ñ Ö Ø ÓÒ× ØÙÖ Ó 
Ø Ú Ê 
ÓÖ ØÓ Ò
Ö Ñ ÒØ ÐÐÝ ÑÓ Ý ÝÓÙÖ Ø × ¸ Ò
Ø Ò Ö Ò Ö Ø Ø × ×
 Ñ Ò Ø ÓÒº

Ø Ú Ê 
ÓÖ Ë
 Ñ º Ò ´ Ú Ö× ÓÒ ¾µ Ó

Ö Ø Ø Ð 
ÓÒØ ÜØ× ¸ ÓÖ
 ØÖÙ Ó Ø
غ
ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò
Ò

Ö Ø Ø Ð ÔÖÓ 
Ø× ¸ ÓÖ
 ØÖÙ Ó Ø
غ
ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò
غ
ÓÐÙÑÒ ×
Ö ÔØ ÓÒ ¸ Ø ÜØ
Ò
Ò
Para terminar, vamos gerar a tabela e o modelo de ações:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ» Ò Ö Ø ÑÓ Ð 
Ø ÓÒ
Ü ×Ø× ÔÔ»ÑÓ Ð×»
Ü ×Ø× Ø ×Ø»ÙÒ Ø»
36
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ü ×Ø× Ø ×Ø» ÜØÙÖ ×»

Ö Ø ÔÔ»ÑÓ Ð×» 
Ø ÓÒºÖ

Ö Ø Ø ×Ø»ÙÒ Ø» 
Ø ÓÒ Ø ×ØºÖ

Ö Ø Ø ×Ø» ÜØÙÖ ×» 
Ø ÓÒ׺ÝÑÐ
Ü ×Ø× »Ñ Ö Ø

Ö Ø »Ñ Ö Ø »¼¼¿ 
Ö Ø 
Ø ÓÒ׺Ö
A migração para o modelo seria:

Ð ×× Ö Ø 
Ø ÓÒ× 
Ø Ú Ê 
ÓÖ Å Ö Ø ÓÒ
× Ð ºÙÔ

Ö Ø Ø Ð 
Ø ÓÒ× Ó Ø
غ
ÓÐÙÑÒ ×
Ö ÔØ ÓÒ¸ ×ØÖ Ò
غ
ÓÐÙÑÒ ÓÒ ¸ ÓÓÐ Ò
غ
ÓÐÙÑÒ 
Ö Ø Ø¸ Ø Ø Ñ
غ
ÓÐÙÑÒ 
ÓÑÔÐ Ø Ø¸ Ø Ø Ñ
غ
ÓÐÙÑÒ 
ÓÒØ ÜØ ¸ ÒØ Ö
غ
ÓÐÙÑÒ ÔÖÓ 
Ø ¸ ÒØ Ö
Ò
Ò
× Ð º ÓÛÒ
ÖÓÔ Ø Ð 
Ø ÓÒ×
Ò
Ò
Com isso, já temos agora o suficiente em nosso banco de dados para trabalhar um pouco em
nossa aplicação.
Um recurso muito útil do Rails é o console, que serve tanto para experimentar com as clas-
ses de dados como para executar uma série de outras funções úteis de teste e manutenção da
aplicação. Para acessar o controle, use o seguinte comando:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ»
ÓÒ×ÓÐ
ÄÓ Ò Ú ÐÓÔÑ ÒØ ÒÚ ÖÓÒÑ ÒØº
Obs.: Para executar esse comando é necessário que você tenha instalado o pacote irb.
A exemplo de um console de comando do DOS ou do próprio MySQL, o console do Rails
permite que você insira um comando e veja seus resultados imediatamente:
Por exemplo:
ÓÒØ ÜØº
Ö Ø ´ Ò Ñ ³ÀÓÑ ³µ
ÓÒØ ÜØ ¼Ü ¿
 Ò Û Ö 
ÓÖ Ð× ¸  ÖÖÓÖ× 
Ø Ú Ê 
ÓÖ ÖÖÓÖ× ¼Ü 
 × ÓÒØ ÜØ ¼Ü ¿
 ººº ¸  ÖÖÓÖ× ß ¸  ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½
O comando acima cria e salva um novo contexto, recebendo como parâmetro o nome do
mesmo, descrito por seu único atributo. O resultado, visto logo depois do comando, é uma repre-
sentação textual da classe.
Todos objetos em Ruby, e isso inclui desde números inteiros a classe complexas, possuem
uma representação textual. Na maior parte dos casos, o Ruby gera uma representação textual
37
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
automática para classes que não especificam a sua própria representação e é isso o que você
está vendo acima.
Em uma aplicação, você provavelmente precisará criar um objeto e manipulá-lo antes de
salvá-lo. Isso também é possível, como demonstrado abaixo:

ÓÒØ ÜØ ÓÒØ ÜØºÒ Û
ÓÒØ ÜØ ¼Ü ½ ¼ Ò Û Ö 
ÓÖ ØÖÙ ¸  ØØÖ ÙØ × ß Ò Ñ Ò Ð

ÓÒØ ÜØºÒ Ñ ³ÏÓÖ ³
ÏÓÖ

ÓÒØ ÜØº× Ú
ØÖÙ
No exemplo acima, o objeto é criado, uma de suas propriedade é atribuída e depois disso
o objeto é salvo. A persistência de dados só ocorre na invocação do método save. Outras
operações são possíveis:
ÓÒØ ÜØº Ò ´ Ðе
ÓÒØ ÜØ ¼Ü  ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½ ¸ ÓÒØ ÜØ ¼Ü
 ØØÖ ÙØ × ß Ò Ñ ÏÓÖ ¸ ¾ ℄
ÓÒØ ÜØº Ò ´¾µ
ÓÒØ ÜØ ¼Ü ¾¿¾  ØØÖ ÙØ × ß Ò Ñ ÏÓÖ ¸ ¾
ÓÒØ ÜØº Ò ´ Öר¸ 
ÓÒ Ø ÓÒ× ³Ò Ñ Ð ³¸ ³ÀÓÑ ³℄µ
ÓÒØ ÜØ ¼Ü 

  ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½
A primeira chamada acima retorna todos os registros correspondente aos contextos. Vemos
que o resultado é um array, delimitado por []. A segunda chamada, por sua vez, retorna o objeto
especificado pelo id passado, ou seja, por sua chave primária surrogada. O terceiro método, por
fim, retorna o primeiro registro satisfazendo as condições passadas.
O método find possui vários outros parâmetros que servem para gerar queries complexas sem
esforço, ordenando o resultado, limitando a quantidade de itens retornados, e, para usos mais
avançados, criando joins automaticamente. Veremos exemplos extensos disso mais adiante.
A sofisticação das classes geradas pelo ActiveRecord se estende ao ponto da criação de
métodos automáticos para várias situações. Algumas delas exploraremos depois, mas vale a
pena notar aqui pelo menos uma delas: métodos de busca e criação automáticos.
Por exemplo, é possível executar o comando abaixo para encontrar um contexto pelo seu
nome:
ÓÒØ ÜØº Ò Ý Ò Ñ ´³ÀÓÑ ³µ
ÓÒØ ÜØ ¼Ü 
  ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½
O método find_by_name não existia até ser chamado. Isso pode ser visto verificando a exis-
tência do método, usando respond_to?, que é um método presente em todas as classes Ruby
e, ao receber um símbolo que especifica o nome do método a ser testado, devolve uma valor
indicando se a classe suporta o método ou não:
ÓÒØ ÜØºÖ ×ÔÓÒ ØÓ ´ Ò Ý Ò Ñ µ
38
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ð×
ÓÒØ ÜØº Ò Ý Ò Ñ ´³ÀÓÑ ³µ
ÓÒØ ÜØ ¼Ü ¼
  ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½
Como é fácil perceber, a classe não possui aquele método até que ele seja invocado. Uma
classe de dados Rails aceita combinações quaisquer de seus atributos e de algumas operações
para gerar esse tipo de métodos.
Um exemplo é find_or_create_by_name, que procuraria um registro e o criaria caso não
fosse encontrado, com o nome passado como parâmetro. Se a classe possuir mais atribu-
tos, poderíamos muito bem usar algo como find_or_create_by_name_and_description ou ainda
find_by_description_and_completed_at.
É claro que se usarmos isso para todas as chamadas, teremos métodos com nomes absurda-
mente longos como find_or_create_by_description_and_created_at_and_completed_at_and_done
que ficariam bem melhor como chamadas separadas usando condições por questões de legibili-
dade.
O que estamos fazendo aqui no console é basicamente o que faremos em uma aplicação no
que tange à manipulação de dados. Como você pode ver, na maior parte dos casos, o Rails
não exige que o desenvolvedor escreva código SQL, gerando o código necessário por trás das
cenas, com toda eficiência possível. E caso seja necessário, há ainda duas possilidades: usar
parâmetros mais avançados do método find, que permitem a inserção de fragmentos de SQL em
uma operação qualquer; ou ainda, usar métodos como find_by_sql que permitem um execução
direta no banco com integração plena com o Rails.
Usar as facilidades do Rails não significa que o desenvolvedor não precisa conhecer SQL;
ao contrário, o conhecimento é fundamental, tanto para evitar problemas no uso do próprio Rails
como para todas outras tarefas que existem além do Rails.
Agora que já trabalhamos um pouco com o modelo de dados, vamos passar para a aplicação
em si.
39
Capítulo 5
MVC e CONTROLLER
Essa lição tem como objetivo explicar o que se trata o MVC e como fazer o primeiro CON-
TROLLER
5.1 MVC
Como mencionado anteriormente, o Rails utilizado a estratégia MVC. A parte correspondente
ao Model existe nas classes de dados e é implementada pelo ActiveRecord. Um segundo compo-
nente do Rails, o ActionPack, implementa o V e o C que são respectivamente View e Controller.
Um controller é uma classe responsável por receber as requisições feitas pela aplicação e
executar as ações necessárias para atender essas requisições. Essas ações, ao serem executa-
das, provavelmente causarão mudanças no banco que serão efetuadas, por sua vez, por uma ou
mais classes de dados.
Finalmente, o resultado será exibido através de uma view, que será retornada ao usuário na
forma de HTML, imagens, XML, ou qualquer outra saída aceitável da aplicação.
As três partes da estratégia MVC são independentes no Rails como deveriam ser em qual-
quer boa implementação das mesmas. Qualquer modelo de dados pode ser utilizado indepen-
dentemente, inclusive em scripts que não tem a ver com a aplicação Web em si, como, por
exemplo, tarefas agendadas. Os controllers também são independentes e podem ser usado para
simplesmente efetuar ações que nem mesmo retornam views, atualizando somente o banco ou
disparando outro processo qualquer no servidor. As views são, de certa forma, a parte mais de-
pendente já que, embora podendo ser utilizadas separadamente, não fazem muito sentido sem
utilizarem dados gerados por modelos de dados e controllers.
Para identificar qual controller será responsável por atender uma determinada solicitação da
aplicação, o Rails utiliza uma mecanismo de roteamento de requisições automático que não ne-
cessita de configurações complexas, mas que pode também ser customizado de acordo com as
necessidades de cada aplicação.
A regra principal de roteamento no Rails forma URLs segundo o padrão /controller/action/id,
onde controller é a classe responsável por atender a requisição especificada por aquela URL,
action é um método dentro da classe e id é um parâmetro opcional passado para identificar um
objeto qualquer sobre o qual a ação será efetuada. Como dito anteriormente, esse padrão pode
ser modificado e veremos mais sobre isso adiante no tutorial.
40
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
5.2 O primeiro controller
Vamos começar criando um controller para lidar com a página inicial de nossa aplicação. Para
gerar um controller, usamos o comando abaixo:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ» Ò Ö Ø 
ÓÒØÖÓÐÐ Ö ÓÑ
Ü ×Ø× ÔÔ»
ÓÒØÖÓÐÐ Ö×»
Ü ×Ø× ÔÔ» ÐÔ Ö×»

Ö Ø ÔÔ»Ú Û×» ÓÑ
Ü ×Ø× Ø ×Ø» ÙÒ
Ø ÓÒ Ð»

Ö Ø ÔÔ»
ÓÒØÖÓÐÐ Ö×» ÓÑ 
ÓÒØÖÓÐÐ ÖºÖ

Ö Ø Ø ×Ø» ÙÒ
Ø ÓÒ Ð» ÓÑ 
ÓÒØÖÓÐÐ Ö Ø ×ØºÖ

Ö Ø ÔÔ» ÐÔ Ö×» ÓÑ ÐÔ ÖºÖ
O nome passado para o comando é home, que será usado para compor todos os arquivos
gerados pelo mesmo. Da mesma forma que nos modelos de dados, o Rails cria unit tests para
a classe gerada, que podem ser executados com o comando rake tests. Esse comando roda
todos os unit tests presentes na aplicação e qualquer boa aplicação desenvolvida segundo a
metodologia Extreme Programming faz uso extensivo dessa técnica. Veremos esse assunto em
mais detalhes em uma outra seção de nosso tutorial. Se você acessar a URL desse controller
agora, você vai receber a seguinte tela:
Figura 2
41
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Repare que, nesse caso, eu informei somente /controller/ como a URL, sem passar nem
a parte correspondente a uma ação ou a um id. Nesse caso, o Rails assume que estamos
invocando a ação index sem id. Esse é um mais exemplo de convenção ao invés de configuração.
Ao invés de ter sempre que especificar uma ação padrão em algum lugar, o Rails convenciona
que a ação padrão é index, poupando o desenvolvedor sem afetar a aplicação.
Vamos olhar o arquivo app/controllers/home_controller.rb gerado por nosso comando. Como
já mencionamos, o Rails segue uma estrutura fixa de diretórios, poupando mais uma vez o de-
senvolvedor. Arquivos relacionados ao banco vão em no diretório db, arquivos de configuração
em config e tudo relacionado a MVC vai em app. Dentro de app temos vários outros diretórios
que contém mais partes específicas da aplicação. Em alguns casos, o Rails também adiciona
um sufixo ao arquivo, evitando colisões de nomes e problemas estranhos na aplicação, como é o
caso aqui. O arquivo do controller criado contém o seguinte:

Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò
A classe HomeController define quem que irá responder a requisições padrão em /home.
Ela herda da classe ApplicationController, que está definida no arquivo application.rb, no mesmo
diretório. Sendo assim, qualquer método criado na classe ApplicationController estará automati-
camente disponível nos controllers gerados para a aplicação.
O uso de herança serve mais uma vez para beneficiar o desenvolvedor que pode utilizar um
modelo mental familiar para trabalhar sua aplicação, um modelo que é ao mesmo tempo simples
e poderoso.
Para criarmos a ação index, basta adicionarmos um método à classe:

Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ò
Ò
O princípio que usamos acima é comum a tudo em Rails. Basicamente tudo o que fazemos
em uma aplicação usando o mesmo consiste em extender alguma classe por meio da adição de
métodos customizados. Recarregando a página no navegador, ficamos com o seguinte:
42
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 3
Vamos que, dessa vez, o Rails identificou a ação a ser executada, mas, como a aplicação
não especificou nenhum retorno, houve um erro. Isso aconteceu porque o Rails tentou aplicar
automaticamente uma view para aquela ação do controller. Como a view ainda não existe, temos
o erro. Antes de nos aventurarmos em uma view usando o mecanismo de templates do Rails,
vamos retornar algum texto por contra própria:

Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ö Ò Ö Ø ÜØ ÇÐ
Ò
Ò
O método render, disponível para qualquer controller ou view, gera saída na aplicação, saída
esta que depende de seus parâmetros. No caso acima, estamos renderizando texto puro, como
indicado pelo parâmetro text.
Nossa página agora ficaria assim:
43
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 4
Temos a nossa primeira saída em uma aplicação Rails.
Como escrever manualmente toda a saída não é o que queremos, vamos criar a nossa pri-
meira view. Para isso, criamos o arquivo app/views/home/index.rhtml. A extensão .rhtml indica
que esse arquivo contém HTML e código Ruby.
Uma outra extensão possível seria .rjs para gerar retorno em JavaScript, comumente utilizado
em aplicações Ajax. Há ainda .rxml, para gerar saída em XML. Outros mecanismos de tem-
plate podem usar outras extensões, já que o Rails pode ser configurado para outros mecanismos
alternativos.
Por hora, usaremos a linguagem de templates padrão do Rails. Vamos criar o seguinte ar-
quivo, então:
Ô ÇÐ ¸ ÑÙÒ Ó »Ô
Se recarregamos a página, notaremos que nada mudou. Isso acontece porque estamos
usando render diretamente. Nesse caso, o Rails detecta que alguma saída já foi gerada e não
tenta gerar outra. Basta, então, remover a chamada a render método index, voltando o arquivo a:

Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
44
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ò Ü
Ò
Ò
Agora, recarregando a página, temos:
Figura 5
Sem que haja necessidade de especificar qualquer coisa, o Rails está usando o arquivo ade-
quado. Veja que não configuramos qualquer coisa. Criamos um controller, definimos um método
no mesmo, e criamos um arquivo que contém o que queremos que seja retornado por aquele
método. A simples existência desses arquivos representa uma cadeia de execução sem que
precisamos nos preocupar com que parte da aplicação faz isso ou aquilo.
Qualquer outra ação que fosse criada dentro desse controller seguiria o mesmo padrão. O
nome da ação seria associado a um nome de arquivo dentro de um diretório em app/views cujo
nome seria o do próprio controller. O Rails também é inteligente ao ponto de responder a uma
ação mesmo que o método não exista, desde que a view esteja presente no diretório correto.
45
Capítulo 6
Layouts e Roteamento
Essa lição tem como finalidade facilitar o desenvolvimento da parte visual de uma aplicação.
Para isso, o Rails possui um conceito denominado layouts. E o roteamento é para satisfazer a
URL que foi especificada.
6.1 Layouts
Na maioria das aplicações Web, as páginas variam somente no seu conteúdo principal, pos-
suindo cabeçalhos, rodapés e barras de navegação em comum. Obviamente, um framework cujo
maior objetivo é aumentar a produtividade do desenvolvedor não exigiria que o código para esses
elementos tivesse que ser repetido em cada view. Um layout funciona como um arquivo raiz,
dentro do qual o resultado de uma view é inserido automaticamente.
Mais uma vez favorecendo convenção ao invés de configuração, o Rails define um arquivo pa-
drão de layout que é usado automaticamente por qualquer view a não ser que haja especificação
em contrário. O Rail também é inteligente o bastante para somente usar um layout em views com
a mesma extensão.
O layout padrão para a aplicação fica em um arquivo chamado application.rhtml, dentro do
diretóri app/views/layouts, que não existe ainda.
Se você olhar agora o código gerado pela página que criamos até o momento, você verá o
seguinte:
46
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 6
Como você pode notar, ão estamos gerando nenhum dos elementos HTML geralmente vistos
em uma página comum.
Vamos criar o arquivo application.rhtml no diretório especificado, com o seguinte conteúdo:
ØÑÐ
Ø ØÐ Ì »Ø ØÐ
»
Ó Ý
± Ý Ð ±
» Ó Ý
» ØÑÐ
Temos no arquivo acima, o primeiro exemplo de uso de código Ruby dentro de uma view,
delimitado pelos marcadores % e %. Aqueles familiarizados com PHP e ASP reconhecerão o
estilo de marcadores, com o uso de %= objeto % para retornar conteúdo.
No caso acima, o método especial yield retorna o conteúdo atual gerado pela ação, seja por
meio de uma view ou usando render diretamente. O método yield tem uma conotação especial
47
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
no Ruby, servindo para invocar o bloco associado ao contexto. Inserido em um layout do Rails, o
bloco define a execução da ação, com seu conseqüente retorno de conteúdo.
A nossa página recarregada agora fica como mostrado abaixo:
Figura 7
Não parece muita coisa, mas, olhando o código, você verá o seguinte:
48
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 8
É fácil perceber que o código do layout foi aplicado sobre o código da view, gerando a saída
final da aplicação.
O que precisamos fazer agora é extender o nosso layout para incluir algumas amenidades. O
nosso arquivo application.rhtml poderia ser mudado para o seguinte:
ØÑÐ
Ø ØÐ Ì »Ø ØÐ
± רÝÐ × Ø Ð Ò Ø ÙÐØ ±
»
Ó Ý
± Ý Ð ±
» Ó Ý
» ØÑÐ
O método stylesheet_link_tag recebe o nome de uma stylesheet como parâmetro e gera um
link para a mesma. O nosso código gerado agora ficou assim:
49
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 9
Note que mais uma vez o Rails assumiu um caminho padrão. Nesse caso, o arquivo é servido
diretamente da raiz da aplicação, que é o diretório public. Você pode criar um arquivo chamado
default.css no diretório public/stylesheets para adicioná-lo à aplicação. Um exemplo disso
seria:
Ó Ý
ß
ÓÒØ¹ Ñ ÐÝ Î Ö Ò ¸ Ö Ð¸ × Ò×¹× Ö
ÓÒØ¹× Þ ¼±
Uma coisa a manter em mente é que o layout padrão da aplicação não é, de forma alguma,
o único que pode ser gerado. Você pode criar tantos layouts quanto precisar, colocando-os no
mesmo diretório, de onde estarão acessíveis a toda aplicação.
Para usar um layout diferente em um controler você poderia fazer algo assim:

Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ð ÝÓÙØ ÓÑ
50
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ò Ü
Ò
Ò
O layout cujo nome é home seria especificado no arquivo app/views/layouts/home.rhtml,
com a mesma funcionalidade do arquivo application.rhtml.
Uma outra possibilidade que o Rails oference é sobrescrever um layout para uma única ação,
diretamente no método render. Um exemplo seria:

Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ð ÝÓÙØ ÓÑ
Ò Ü
Ò
Ò Ü ×Ô 
 Ð
Ö Ò Ö 
Ø ÓÒ Ð ×Ø ¸ Ð ÝÓÙØ ÓÑ ×Ô 
 Ð
Ò
Ò
Você pode também suprimir inteiramente um layout usando :layout = false.
Finalmente, você pode usar maneiras específicas de determinar o layout de uma página. Por
exemplo:

Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ð ÝÓÙØ 
 ÓÓ× Ð ÝÓÙØ
Ò Ü
Ò
ÔÖÓØ 
Ø

 ÓÓ× Ð ÝÓÙØ
´
ÙÖÖ ÒØ Ù× Öº Ñ Ò µ Ñ Ò ×ØÖ Ø ÓÒ ÒÓÖÑ Ð
Ò
Ò
No caso acima, dependendo do retorno da chamada ao método admin?, a aplicação poderia
usar o layout definido no arquivo administration.rhtml ou no arquivo normal.rhtml. Como podemos
ver não há muitos limites para o que pode ser feito.
6.2 Roteamento
Se você acessou a URL raiz da aplicação, você terá notado que ela não mudou, apesar do
controller que criamos. Isso acontece porque o Rails define um arquivo index.html que serve
como padrão. Se removermos esse arquivo do diretório public, ficaremos com a seguinte página:
51
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 10
Esse erro indica que o Rails não consegue encontrar um roteamento que satisfaça a URL que
especificamos. Para resolvermos o problema, vamos editar o arquivo config/routes.rb, que define
esses roteamentos. Esse arquivo contém o seguinte codigo:

Ø ÓÒ ÓÒØÖÓÐÐ Ö ÊÓÙØ Ò ÊÓÙØ ׺ Ö Û Ó Ñ Ô
Ì ÔÖ ÓÖ ØÝ × × ÙÔÓÒ ÓÖ Ö Ó 
Ö Ø ÓÒ Öר 
Ö Ø ¹ ר ÔÖ ÓÖ ØÝº
Ë ÑÔÐ Ó Ö ÙÐ Ö ÖÓÙØ
Ñ Ôº
ÓÒÒ 
Ø ³ÔÖÓ Ù
Ø×» ³¸ 
ÓÒØÖÓÐÐ Ö ³
 Ø ÐÓ ³¸ 
Ø ÓÒ ³Ú Û³
Ã Ô Ò Ñ Ò ÝÓÙ 
 Ò ×× Ò Ú ÐÙ × ÓØ Ö Ø Ò 
ÓÒØÖÓÐÐ Ö Ò 
Ø ÓÒ
Ë ÑÔÐ Ó Ò Ñ ÖÓÙØ
Ñ ÔºÔÙÖ
 × ³ÔÖÓ Ù
Ø×» »ÔÙÖ
 × ³¸ 
ÓÒØÖÓÐÐ Ö ³
 Ø ÐÓ ³¸ 
Ø ÓÒ ³ÔÙÖ
 × ³
Ì × ÖÓÙØ 
 Ò ÒÚÓ Û Ø ÔÙÖ
 × ÙÖд ÔÖÓ Ù
غ µ
ÓÙ 
 Ò Ú Ø ÖÓÓØ Ó ÝÓÙÖ × Ø ÖÓÙØ Ý ÓÓ Ò ÙÔ ³³
¹¹ Ùר Ö Ñ Ñ Ö ØÓ Ð Ø ÔÙ Ð 
» Ò Üº ØÑк
Ñ Ôº
ÓÒÒ 
Ø ³³¸ 
ÓÒØÖÓÐÐ Ö Û Ð
ÓÑ
ÐÐÓÛ ÓÛÒÐÓ Ò Ï Ë ÖÚ 
 ÏË Ä × Ð Û Ø Ò ÜØ Ò× ÓÒ
Òר Ó Ð Ò Ñ ³Û× Ð³
Ñ Ôº
ÓÒÒ 
Ø ³ 
ÓÒØÖÓÐÐ Ö»× ÖÚ 
 ºÛ× Ð³¸ 
Ø ÓÒ ³Û× Ð³
52
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
ÁÒר ÐÐ Ø ÙÐØ ÖÓÙØ × Ø ÐÓÛ ×Ø ÔÖ ÓÖ ØÝº
Ñ Ôº
ÓÒÒ 
Ø ³ 
ÓÒØÖÓÐÐ Ö» 
Ø ÓÒ» ³
Ò
Como os comentários dizem, esse arquivo define roteamentos de URLs para controllers. Cada
roteamento é examinado quando uma URL é processada pelo Rails, da primeira para a última,
sendo a ordem de declaração a definição de prioridade.
Como você pode ver no arquivo acima, a URL padrão que mencionamos, /controller/action/id
é a última a ser definida, sendo a aplicada caso não haja instruções em contrário. O roteamento
no Rails é bem rico e trabalharemos alguns dos conceitos do mesmo mais adiante. No momento,
queremos apenas resolver o problema da página inicial.
Essa página é representada no arquivo acima pela linha abaixo, comentada no momento.
Ñ Ôº
ÓÒÒ 
Ø ³³¸ 
ÓÒØÖÓÐÐ Ö Û Ð
ÓÑ
Para mapear o controller home como nossa página inicial, basta modificar a linha para dizer o
seguinte:
Ñ Ôº
ÓÒÒ 
Ø ³³¸ 
ÓÒØÖÓÐÐ Ö ÓÑ
A rota vazia é um sinônimo para a rota raiz e estamos dizendo, com o código acima que se a
mesma for invocada, a requisição deve ser servida pelo controller que definimos anteriormente.
Note a mistura de aspas simples e aspas duplas nesse arquivo. No Ruby, elas são relativa-
mente intercambiáveis e são apenas duas das várias formas de representar texto nessa lingua-
gem. A diferença é que as aspas duplas permitem a interpolação de variáveis como veremos
mais adiante no tutorial. Eu tendo a favorecer o uso de aspas duplas, nas isso é uma opção
pessoal.
Agora, recarregando nossa página inicial temos:
53
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 11
Note que agora o mesmo controller serve dois roteamentos. Essa é apenas uma das possibi-
lidades mais simples que estão disponíveis com o roteamento do Rails.
Agora que temos um conhecimento básico de models, controllers e views, podemos combinar
o três.
54
Capítulo 7
Scaffolding e Validações
Para ajudar na rápida prototipação de aplicações, o Rails possui algo chamado de scaffolding.
E Validações, como o próprio nome indica, são um modo de garantir a integridade dos dados em
uma aplicação.
7.1 Scaffolding
O scaffolding provê uma estrutura básica para operações CRUD (Create, Retrieve, Update
and Delete), ou seja, aquelas operações básicas que temos na manipulação de dados, gerando
interfaces rápidas que podem apoiar o desenvolvimento até que você insira a codificação neces-
sária.
Para experimentar com isso e expandir um pouco nossa aplicação, vamos criar um novo
controller, que servirá para administrar os nossos contextos:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ» Ò Ö Ø 
ÓÒØÖÓÐÐ Ö 
ÓÒØ ÜØ×
Ü ×Ø× ÔÔ»
ÓÒØÖÓÐÐ Ö×»
Ü ×Ø× ÔÔ» ÐÔ Ö×»

Ö Ø ÔÔ»Ú Û×»
ÓÒØ ÜØ×
Ü ×Ø× Ø ×Ø» ÙÒ
Ø ÓÒ Ð»

Ö Ø ÔÔ»
ÓÒØÖÓÐÐ Ö×»
ÓÒØ ÜØ× 
ÓÒØÖÓÐÐ ÖºÖ

Ö Ø Ø ×Ø» ÙÒ
Ø ÓÒ Ð»
ÓÒØ ÜØ× 
ÓÒØÖÓÐÐ Ö Ø ×ØºÖ

Ö Ø ÔÔ» ÐÔ Ö×»
ÓÒØ ÜØ× ÐÔ ÖºÖ
Inicialmente, esse controller é como o que criamos anteriormente, para a home da aplicação,
e não possui nenhuma ação pré-definida.
Vamos editar o seu arquivo, em app/controllers/contexts_controller.rb, acrescentando uma
linha de código:

Ð ×× ÓÒØ ÜØ× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
×
 ÓÐ 
ÓÒØ ÜØ
Ò
Agora, acesse a URL desse controller, digitando http://localhost:3000/contexts no navega-
dor que você estiver usando:
55
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 12
Sem nenhuma linha de código além da inserida acima, temos listagem, inserção, atualização
e remoção de contextos.
Clique em New context para experimentar:
56
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 13
Depois, clicando em Create, temos:
57
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 14
E, finalmente, clicando em Show, vemos:
58
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 15
Note, que na tela acima, o id do objeto já aparece na URL. Nesse caso é 5 porque eu já
experimentara antes com outros objetos.
O scaffolding é muito útil na geração de controllers básicos de administração para dar apoio
à prototipação e ao início do desenvolvimento, principalmente para cadastros, permitindo que o
desenvolvedor se foque no que é mais importante para a aplicação. O inconveniente é que as
ações geradas são bem limitadas e não podem ser editadas ou traduzidas.
Para expandir um pouco a funcionalidade, existe outra forma de geração de scaffolding que
permite uma flexibilidade maior na edição das páginas geradas, que podem, inclusive, ser utiliza-
das como base para as páginas finais.
Para isso, use o comando abaixo:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ» Ò Ö Ø ×
 ÓÐ 
ÓÒØ ÜØ
Ü ×Ø× ÔÔ»
ÓÒØÖÓÐÐ Ö×»
Ü ×Ø× ÔÔ» ÐÔ Ö×»
Ü ×Ø× ÔÔ»Ú Û×»
ÓÒØ ÜØ×
Ü ×Ø× Ø ×Ø» ÙÒ
Ø ÓÒ Ð»
Ô Ò Ò
Ý ÑÓ Ð
Ü ×Ø× ÔÔ»ÑÓ Ð×»
59
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ü ×Ø× Ø ×Ø»ÙÒ Ø»
Ü ×Ø× Ø ×Ø» ÜØÙÖ ×»
ÒØ 
 Ð ÔÔ»ÑÓ Ð×»
ÓÒØ ÜØºÖ
ÒØ 
 Ð Ø ×Ø»ÙÒ Ø»
ÓÒØ ÜØ Ø ×ØºÖ
ÒØ 
 Ð Ø ×Ø» ÜØÙÖ ×»
ÓÒØ ÜØ×ºÝÑÐ

Ö Ø ÔÔ»Ú Û×»
ÓÒØ ܨ׻ ÓÖÑºÖ ØÑÐ

Ö Ø ÔÔ»Ú Û×»
ÓÒØ ÜØ×»Ð ×ØºÖ ØÑÐ

Ö Ø ÔÔ»Ú Û×»
ÓÒØ ÜØ×»× ÓÛºÖ ØÑÐ

Ö Ø ÔÔ»Ú Û×»
ÓÒØ ÜØ×»Ò ÛºÖ ØÑÐ

Ö Ø ÔÔ»Ú Û×»
ÓÒØ ܨ׻ ØºÖ ØÑÐ
ÓÚ ÖÛÖ Ø ÔÔ»
ÓÒØÖÓÐÐ Ö×»
ÓÒØ ÜØ× 
ÓÒØÖÓÐÐ ÖºÖ Ò Õ℄ Ý
ÓÖ
 ÔÔ»
ÓÒØÖÓÐÐ Ö×»
ÓÒØ ÜØ× 
ÓÒØÖÓÐÐ ÖºÖ
ÓÚ ÖÛÖ Ø Ø ×Ø» ÙÒ
Ø ÓÒ Ð»
ÓÒØ ÜØ× 
ÓÒØÖÓÐÐ Ö Ø ×ØºÖ Ò Õ℄ Ý
ÓÖ
 Ø ×Ø» ÙÒ
Ø ÓÒ Ð»
ÓÒØ ÜØ× 
ÓÒØÖÓÐÐ Ö Ø ×ØºÖ
ÒØ 
 Ð ÔÔ» ÐÔ Ö×»
ÓÒØ ÜØ× ÐÔ ÖºÖ

Ö Ø ÔÔ»Ú Û׻РÝÓÙØ×»
ÓÒØ ÜØ×ºÖ ØÑÐ

Ö Ø ÔÙ Ð 
»×ØÝÐ × Ø×»×
 ÓÐ º
××
Note que, para a geração de um scaffold por esse comando, o nome do modelo de dados é
que deve ser passado como parâmetro, e não o nome do controller. O Rails é capaz de derivar
um do outro.
Esse comando gera a classe do modelo de dados, o controller e views para cada ação CRUD
necessária. No caso acima, como o model já existia, ele não foi criado, e foi necessário sobres-
crever alguns arquivos.
Há duas coisas a serem notadas aqui. Primeiro, o scaffold gerou o seu próprio layout, com
sua própria stylesheet. Por causa disso, o layout original da aplicação foi perdido. Uma solução
aqui será remover o arquivo app/views/layouts/contexts.rhtml, já que não precisamos dele,
e adicionar a stylesheet scaffold.css ao arquivo application.rhtml. Segundo, as views criadas
continuam razoavelmente limitadas, como veremos adiante. Abrindo o novo arquivo gerado do
controller, temos o seguinte:

Ð ×× ÓÒØ ÜØ× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ ³Ð ר³
Ò
Ì× × ÓÙÐ × ´× ØØÔ »»ÛÛÛºÛ¿ºÓÖ »¾¼¼½»Ø » Ó
»Û ÒÌÓÍ× Øº ØÑе
Ú Ö Ý Ñ Ø Ó ÔÓר¸ ÓÒÐÝ ×ØÖÓݸ 
Ö Ø ¸ ÙÔ Ø ℄¸
Ö Ö 
Ø ØÓ ß 
Ø ÓÒ Ð ×Ø
Ð ×Ø

ÓÒØ ÜØ Ô ×¸ 
ÓÒØ ÜØ× Ô Ò Ø 
ÓÒØ ܨ׏ Ô Ö Ô ½¼
Ò
× ÓÛ

ÓÒØ ÜØ ÓÒØ ÜØº Ò ´Ô Ö Ñ× ℄µ
Ò
Ò Û

ÓÒØ ÜØ ÓÒØ ÜØºÒ Û
Ò
60
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF

Ö Ø

ÓÒØ ÜØ ÓÒØ ÜØºÒ Û´Ô Ö Ñ× 
ÓÒØ ÜØ℄µ

ÓÒØ ÜØº× Ú
Ð × ÒÓØ 
 ℄ ³ ÓÒØ ÜØ Û × ×Ù

 ×× ÙÐÐÝ 
Ö Ø º³
Ö Ö 
Ø ØÓ 
Ø ÓÒ ³Ð ר³
Ð×
Ö Ò Ö 
Ø ÓÒ ³Ò Û³
Ò
Ò
Ø

ÓÒØ ÜØ ÓÒØ ÜØº Ò ´Ô Ö Ñ× ℄µ
Ò
ÙÔ Ø

ÓÒØ ÜØ ÓÒØ ÜØº Ò ´Ô Ö Ñ× ℄µ

ÓÒØ ÜØºÙÔ Ø ØØÖ ÙØ ×´Ô Ö Ñ× 
ÓÒØ ÜØ℄µ
Ð × ÒÓØ 
 ℄ ³ ÓÒØ ÜØ Û × ×Ù

 ×× ÙÐÐÝ ÙÔ Ø º³
Ö Ö 
Ø ØÓ 
Ø ÓÒ ³× ÓÛ³¸ 
ÓÒØ ÜØ
Ð×
Ö Ò Ö 
Ø ÓÒ ³ س
Ò
Ò
רÖÓÝ
ÓÒØ ÜØº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ
Ö Ö 
Ø ØÓ 
Ø ÓÒ ³Ð ר³
Ò
Ò
O resultado final, ao ser executado, é muito parecido com o do método scaffold, com a maior
diferença sendo os arquivos de gerados enquanto que, do modo anterior, as ações eram dinami-
camente criadas pelo Rails. Algumas amenidades, como paginação, também foram introduzidas.
Uma consideração deve ser feita aqui: o scaffolding é apenas um apoio à prototipação. Ele
não deve ser usado como uma muleta, gerando páginas para modificação. Se você quer adminis-
trações prontas, existem plugins para o Rails que permitem a geração de páginas bem avançadas.
Esses plugins podem ser utilizados para criar administrações prontas a exemplo das geradas pelo
Django (o framework equivalente ao Rails para o Python), mas mesmo elas tem suas limitações
e inflexibilidades. A lição é sempre procurar o que é melhor para a sua aplicação. Os scaffoldings
são uma visão muito linear de uma aplicação e não levam em contra interfaces alternativas de
melhor usabilidade.
De qualquer forma, o scaffolding gerado é uma boa oportunidade para ver o relacionamento
entre controllers, views e models. Se você tomar uma ação qualquer como exemplo, verá que
ela usa a classe de dados para o acesso ao banco e empacota os dados recebidos em variáveis
fechadas que serão usadas por uma view, evitando que o código de apresentação se misture
com a lógica de negócio. Mesmo elementos do próprio controller, como paginação, são incluidos
nessa discriminação. Veja a view de listagem, por exemplo, descrita no arquivo list.rhtml no
diretório app/views/contexts:
½ Ä ×Ø Ò 
ÓÒØ ÜØ× » ½
Ø Ð
ØÖ
61
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
± ÓÖ 
ÓÐÙÑÒ Ò ÓÒØ ÜØº
ÓÒØ ÒØ 
ÓÐÙÑÒ× ±
Ø ± 
ÓÐÙÑÒº ÙÑ Ò Ò Ñ ± »Ø
± Ò ±
»ØÖ
± ÓÖ 
ÓÒØ ÜØ Ò 
ÓÒØ ÜØ× ±
ØÖ
± ÓÖ 
ÓÐÙÑÒ Ò ÓÒØ ÜØº
ÓÒØ ÒØ 
ÓÐÙÑÒ× ±
Ø ± 
ÓÒØ ÜØº× Ò ´
ÓÐÙÑÒºÒ Ñ µ ± »Ø
± Ò ±
Ø ± Ð Ò ØÓ ³Ë ÓÛ³¸ 
Ø ÓÒ ³× ÓÛ³¸ 
ÓÒØ ÜØ ± »Ø
Ø ± Ð Ò ØÓ ³ س¸ 
Ø ÓÒ ³ س¸ 
ÓÒØ ÜØ ± »Ø
Ø ± Ð Ò ØÓ ³ רÖÓݳ¸ ß 
Ø ÓÒ ³ רÖÓݳ¸ 
ÓÒØ ÜØ ¸ 
ÓÒ ÖÑ ³ Ö ÝÓ
ÔÓר ØÖÙ ± »Ø
»ØÖ
± Ò ±
»Ø Ð
± Ð Ò ØÓ ³ÈÖ Ú ÓÙ× Ô ³¸ ß Ô 
ÓÒØ ÜØ Ô ×º
ÙÖÖ ÒØºÔÖ Ú ÓÙ×

ÓÒØ ÜØ Ô ×º
ÙÖÖ ÒØºÔÖ Ú ÓÙ× ±
± Ð Ò ØÓ ³Æ ÜØ Ô ³¸ ß Ô 
ÓÒØ ÜØ Ô ×º
ÙÖÖ ÒØºÒ ÜØ 
ÓÒØ ÜØ Ô ×º
ÙÖÖ ÒØº
Ö »
± Ð Ò ØÓ ³Æ Û 
ÓÒØ ÜØ³¸ 
Ø ÓÒ ³Ò Û³ ±
O método paginate, usado no controller esconde a complexidade de acesso ao banco fazendo
a busca dos dados, dividindo os itens retornados pelo número de itens requeridos por página e
retornando duas variáveis que contém, respectivamente, uma lista das páginas (que pode ser
usada na view para gerar a numeração das mesmas) e os itens referentes àquela página. Se
você cadastrar mais de 10 itens, verá isso em funcionamento, embora o scaffold gerado se limite
à navegação para frente e para trás na lista de páginas.
A view acima também exibe uma complexidade maior, utilizando vários métodos para a ge-
ração do seu conteúdo. Notadamente, o método link_to que recebe como o texto do link e pa-
râmetros adicionais para a geração da URL, que podem ser combinados de várias formas. Por
exemplo:
± Ð Ò ØÓ 
ÓÒØÖÓÐÐ Ö ÓÑ ±
± Ð Ò ØÓ 
ÓÒØÖÓÐÐ Ö 
ÓÒØ ÜØ× ¸ 
Ø ÓÒ Ø ¸ ¾ ±
± Ð Ò ØÓ 
ÓÒØÖÓÐÐ Ö ÐÓ Ò ¸ Ù× Ò 
ÓÓ × ±
No primeiro caso acima, o método gera a URL raiz para um controller, que como vimos é
mapeada para a ação index. No segundo caso, uma URL completa é retornada. E no terceiro,
um parâmetro using é adicionado à requisição, gerando a seguinte URL: /login?using=cookies.
O método link_to possui várias outras capacidades entre as quais gerar confirmações em
JavaScript e criar forms para submissão confiável de links que modificam destrutivamente seus
dados, como pode ser visto nos próprios arquivos geados nesse scaffold. Uma olhada na do-
cumentação é recomendada para um esclarecimento maior dessas opções. Um outro conceito
interessante apresentado nesse scaffold é o de partials (parciais), que são fragmentos de pági-
nas que podem ser compartilhados entre views, da mesma forma que um layout pode usar várias
views. Veja, por exemplo, a relação entre os dois arquivos abaixo: Primeiro, a view para criação
de um novo registro:
62
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
½ Æ Û 
ÓÒØ ÜØ » ½
± ר ÖØ ÓÖÑ Ø 
Ø ÓÒ ³
Ö Ø ³ ±
± Ö Ò Ö Ô ÖØ Ð ³ ÓÖѳ ±
± ×Ù Ñ Ø Ø Ö Ø ±
± Ò ÓÖÑ Ø ±
± Ð Ò ØÓ ³ 
 ³¸ 
Ø ÓÒ ³Ð ר³ ±
Agora, a view para edição de um registro:
½ Ø Ò 
ÓÒØ ÜØ » ½
± ר ÖØ ÓÖÑ Ø 
Ø ÓÒ ³ÙÔ Ø ³¸ 
ÓÒØ ÜØ ±
± Ö Ò Ö Ô ÖØ Ð ³ ÓÖѳ ±
± ×Ù Ñ Ø Ø ³ س ±
± Ò ÓÖÑ Ø ±
± Ð Ò ØÓ ³Ë ÓÛ³¸ 
Ø ÓÒ ³× ÓÛ³¸ 
ÓÒØ ÜØ ±
± Ð Ò ØÓ ³ 
 ³¸ 
Ø ÓÒ ³Ð ר³ ±
Note que o código gerado é muito parecido (de fato os dois arquivos e suas ações relaciona-
das poderiam ser combinados em um único ponto de acesso) e em ambos os arquivos há uma
chamada ao método render, usando um partial. Esse partial se encontra no arquivo _form.rhtml,
no mesmo diretório. Arquivos que definem partials sempre começam com _ para especificar que
são fragmentos. O conteúdo do arquivo é simples:
± ÖÖÓÖ Ñ ×× × ÓÖ ³
ÓÒØ ÜØ³ ±
¹¹ ÓÖÑ 
ÓÒØ ÜØ℄¹¹
Ô Ð Ð ÓÖ 
ÓÒØ ÜØ Ò Ñ Æ Ñ »Ð Ð Ö»
± Ø ÜØ Ð ³
ÓÒØ ÜØ³¸ ³Ò Ñ ³ ± »Ô
¹¹ Ó ÓÖÑ 
ÓÒØ ÜØ℄¹¹
Nesse caso, a parte do formulário que é comum tanta à inserção de um contexto quanto à sua
edição.
Partials são uma das grandes facilidades do Rails, sendo utilizados principalmente em aplica-
ções Ajax para gerar somente os fragmentos do código necessários para atualizações de partes
de uma página. Hoje, com o uso do templates RJS, eles se tornaram ainda mais importantes.
Se você utilizar o scaffold gerado, verá que o código é um pouco mais polido, com mensagens
de sucesso e paginação, mas com pouco diferença do que poderia ser feito com uma única linha
de código, como visto anteriormente. Por isso, a observação anterior de que scaffolds são utéis,
mas não devem se tornar uma regra na aplicação. Um grande exemplo das limitações é o modo
como os scaffolds básicos do Rails geram as tabelas de listagens, fazendo invocações diretas
aos atributos de um objeto em um loop com pouca possibilidade de customização.
Veja o fragmento de código abaixo, proveniente da view index.rhtml:
ØÖ
± ÓÖ 
ÓÐÙÑÒ Ò ÓÒØ ÜØº
ÓÒØ ÒØ 
ÓÐÙÑÒ× ±
Ø ± 
ÓÐÙÑÒº ÙÑ Ò Ò Ñ ± »Ø
± Ò ±
»ØÖ
63
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Os cabeçalhos da tabela de listagem são gerados fazendo uma iteração sobre as colunas
de conteúdo do modelo de dados em questão, que não incluem colunas avançadas de relacio-
namento e nem são capazes de fazer a tradução adequada de colunas que contenham valores
booleanos, enumerados e tipos de dados próprios do banco. Além disso, o método human_name
é voltado para o idioma inglês e embora exista a possibilidade de adaptá-lo para outro idioma
por meio de plugins e outros métodos, as limitações dessas técnicas são logo aparentes e, se
cuidado não for tomado, podem levar a problemas de lógica na aplicação, tornando a mesma
desnecessariamente complexa e violando os princípios básicos de simplicidade sobre os quais o
Rails foi construído.
Aproveitando momentaneamente o código gerado, vamos avançar um pouco em nossa apli-
cação, fazendo uso de mais uma característica no Rails.
7.2 Validações
O modelo de validações que o Rails fornece é bastante completo e pode ser facilmente ex-
pandido pelo desenvolvedor caso ele necessite de algo não fornecido por padrão nas bibliotecas.
No caso da nossa classe de dados inicial, precisamos validar pelo menos o fato do usuário
ter informado o nome do contexto ao cadastrá-lo.
Para isso, vamos abrir o arquivo da classe, que está em app/models/context.rb, e editá-lo,
inserindo uma validação simples:

Ð ×× ÓÒØ ÜØ 
Ø Ú Ê 
ÓÖ ×
Ú Ð Ø × ÔÖ × Ò
 Ó Ò Ñ
Ò
Se você tentar inserir agora um contexto sem nome, verá o seguinte:
64
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 16
A menos que o usuário informe o nome do contexto, o Rails não permitirá que o objeto seja
salvo. Note que a validação é feita no modelo de dados e refletida na view através dos métodos
da mesma.
O método error_messages_for recolhe todas as mensagens de erro geradas durante uma va-
lidação e gera o HTML necessário para exibi-las, que, no caso acima, ainda é formatado pela
stylesheet scaffold.css criada anteriormente. Da mesma forma, os métodos responsáveis pela
geração dos itens de formulário (como text_field, text_area, select e datetime_select, entre ou-
tros) são capazes de verificar se o campo a que se referem não falhou em alguma validação e
encapsular a exibição do campo em uma indicação de erro.
Múltiplas validações podem ser efetuadas em um mesmo campo. Por exemplo, para prevenir
a inserção de nomes duplicados, a seguinte condição poderia ser colocada na classe:

Ð ×× ÓÒØ ÜØ 
Ø Ú Ê 
ÓÖ ×
Ú Ð Ø × ÔÖ × Ò
 Ó Ò Ñ
Ú Ð Ø × ÙÒ ÕÙ Ò ×× Ó Ò Ñ
Ò
O resultado seria:
65
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 17
As mensagens de erro geradas são padronizadas no próprio Rails, mas podem ser customi-
zadas usando o seguinte formato:

Ð ×× ÓÒØ ÜØ 
Ø Ú Ê 
ÓÖ ×
Ú Ð Ø × ÔÖ × Ò
 Ó Ò Ñ
Ú Ð Ø × ÙÒ ÕÙ Ò ×× Ó Ò Ñ ¸ Ñ ×× ÑÙר ÙÒ ÕÙ
Ò
Note que o método error_messages_for é voltado para o inglês, formando frases que fazem
mais sentido nesse idioma, enquanto o nosso português prefere frases mais elaboradas. É facil
substituir o método acima por uma implementação mais interessante do mesmo que atenda ao
português e como veremos mais adiante, em outra seção do tutorial.
Um último passo seria atualizar esse scaffold para usar o layout que criamos. Para isso, re-
mova o arquivo contexts.rhtml e atualize o arquivo application.rhtml (ambos no diretório app/views/layouts)
para o seguinte:
ØÑÐ
Ø ØÐ Ì »Ø ØÐ
66
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
± רÝÐ × Ø Ð Ò Ø ÙÐØ ±
± רÝÐ × Ø Ð Ò Ø ×
 ÓÐ ±
»
Ó Ý
± Ý Ð ±
» Ó Ý
» ØÑÐ
A mudança não é grande, mas significa que nosso scaffold agora usa o layout da aplicação,
recebendo todas as modificações provenientes do mesmo. Cabe uma nota aqui sobre as ações
geradas no scaffold e, por extensão, qualquer outra ação a ser criada em uma aplicação. Um
movimento dentro da comunidade do Rails hoje é o uso de métodos REST, que representam uma
interpretação de um conjunto de padrões e filosofias de desenvolvimento Web. Esses métodos
usam verbos HTTP mais específicos como PUT e DELETE para efetuar suas ações, ao invés de
usar somente os usuais GET e POST. A próxima versão do Rails, ao que tudo indica, virá com um
suporte bem forte para esse tipo de uso. O presente tutorial não entrará nesses detalhes sobre
isso, mas deixo ao leitor alguns recursos para que ele possa pesquisar mais sobre o assunto:
ØØÔ »»ÛÛÛºÜÑк
ÓÑ»ÔÙ » »¾¼¼ »½½»¼¾»Ö ר¹ÓÒ¹Ö Ð׺ ØÑÐ
ØØÔ »»Ô ÞÖ º Ö ÐÝ ÒÓÙ ºÓÖ » ÐÓ »¾¼¼ »¼¿» ÒÓØ Ö¹Ö ×Ø¹
ÓÒØÖÓÐÐ Ö¹ ÓÖ¹Ö Ð×»
ØØÔ »»ÛÛÛº Ð Û Ú ÐÓÔÑ ÒØº
ÓÑ»ÔÐÙ Ò×»× ÑÔÐÝÖ ×Ø ÙÐ
Agora que vimos com o básico funciona no Rails, podemos partir para tentar a nossa própria
implementação, aprendendo mais sobre com as coisas funcionam.
67
Capítulo 8
Segundo Controller
Nessa lição, vamos criar o cadastro de projeto, que também é bem simples, de forma mais
manual para entendermos como uma aplicação comum processa seus dados. Para facilitar,
vamos combinar a criação e edição de um registro em uma única ação.
8.1 Início
O primeiro passo é atualizar o modelo de dados para efetuar validações. No caso no nosso
modelo de dados para projetos (que está no arquivo app/models/project.rb), precisamos de va-
lidações igualmente simples. A classe ficaria, assumindo que o atributo description é opcional,
assim:

Ð ×× ÈÖÓ 
Ø 
Ø Ú Ê 
ÓÖ ×
Ú Ð Ø × ÔÖ × Ò
 Ó Ò Ñ
Ú Ð Ø × ÙÒ ÕÙ Ò ×× Ó Ò Ñ
Ò
Um segundo passo é gerar um controller para lidar com as requisições relacionadas ao ca-
dastro de projetos. Dessa vez, vamos usar o comando de geração do controllers especificando
já as ações que desejamos criar automaticamente. Basicamente, queremos as ações index, list,
edit e delete. A ação index existe para não precisarmos de uma regra de roteamento explícita
mas será meramente uma invocação da ação list. E ação edit resumirá todas as ações de criação
e inserção, simplicando o código. O comando para gerar controller é o seguinte:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ» Ò Ö Ø 
ÓÒØÖÓÐÐ Ö ÔÖÓ 
Ø× Ò Ü Ð ×Ø Ø Ð Ø
Ü ×Ø× ÔÔ»
ÓÒØÖÓÐÐ Ö×»
Ü ×Ø× ÔÔ» ÐÔ Ö×»

Ö Ø ÔÔ»Ú Û×»ÔÖÓ 
Ø×
Ü ×Ø× Ø ×Ø» ÙÒ
Ø ÓÒ Ð»

Ö Ø ÔÔ»
ÓÒØÖÓÐÐ Ö×»ÔÖÓ 
Ø× 
ÓÒØÖÓÐÐ ÖºÖ

Ö Ø Ø ×Ø» ÙÒ
Ø ÓÒ Ð»ÔÖÓ 
Ø× 
ÓÒØÖÓÐÐ Ö Ø ×ØºÖ

Ö Ø ÔÔ» ÐÔ Ö×»ÔÖÓ 
Ø× ÐÔ ÖºÖ

Ö Ø ÔÔ»Ú Û×»ÔÖÓ 
Ø×» Ò ÜºÖ ØÑÐ

Ö Ø ÔÔ»Ú Û×»ÔÖÓ 
Ø×»Ð רºÖ ØÑÐ

Ö Ø ÔÔ»Ú Û×»ÔÖÓ 
Ø×» ØºÖ ØÑÐ

Ö Ø ÔÔ»Ú Û×»ÔÖÓ 
Ø×» Ð Ø ºÖ ØÑÐ
68
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Como você pode ver, os arquivos das views foram automaticamente criados, e se você abrir o
arquivo do controller em si (app/controllers/projects_controller.rb) você verá o esqueleto que
foi gerado:

Ð ×× ÈÖÓ 
Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ò
Ð ×Ø
Ò
Ø
Ò
Ð Ø
Ò
Ò
Invocando o controller em seu navegador, você verá o seguinte:
Figura 18
Nós agora temos um controller que responde perfeitamente às nossas ações, com views já
associadas, prontas para o uso.
69
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Como a ação index é somente uma invocação da ação list, podemos remover o arquivo da
view da mesma que está em app/views/projects/index.rhtml e começar a editar as ações. O
método index é muito simples:

Ð ×× ÈÖÓ 
Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
Ò
Ø
Ò
Ð Ø
Ò
Ò
O que essas duas linhas nos dizem são: primeiro, invoque o método list, e depois renderize a
view da ação list. Mesmo representando uma ação em si, list não passa de um método comum
da classe. É somente a mágica do Rails que o torna uma ação, e, sendo assim, ele pode ser
invocado normalmente, como qualquer outra método. A segunda linha é necessária porque o
mecanismo automático de identificação de views procuraria a view relacionada a index e não a
list. Precisamos, então, explicitar a que será usada pela aplicação.
Antes de construirmos a ação list, precisamos providenciar um modo de inserirmos registros
do banco. Para isso, precisamos criar a nossa ação edit. Temos duas situações possíveis: ou o
usuário está criando um novo registro, ou ele está atualizando um registro existente. Obviamente,
a única diferença entre esses dois métodos é a existência ou não do objeto. E a primeira coisa
a ser feita tanto na criação quanto na edição de um objeto é exibir o formulário do mesmo para
preenchimento.
Como ações relacionadas somente a exibição geralmente são associadas ao método HTTP
GET enquanto ações que modificam dados e dependem de formulários são invocadas a partir do
método POST, vamos usar essa diferenciação para identificar se estamos salvando o objeto ou
somente exibindo o formulário para edição. E mais, vamos usar a existência ou não do parâmetro
id para identificar se estamos lidando com um novo objeto ou com um objeto já existente. A
primeira versão do nosso método ficaria assim, então:

Ð ×× ÈÖÓ 
Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
Ò
Ø
Ô Ö Ñ× ℄
ÔÖÓ 
Ø ÈÖÓ 
غ Ò ´Ô Ö Ñ× ℄µ
Ð×
ÔÖÓ 
Ø ÈÖÓ 
ØºÒ Û
Ò
70
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ö ÕÙ ×ØºÔÓר
Ò
Ò
Ð Ø
Ò
Ò
O segundo teste do método verifica se estamos recebendo uma requisição POST. Como men-
cionamos anteriormente, é isso que vamos usar para saber se estamos simplesmente exibindo
o formulário (seja vazio ou não), ou se está na hora de persistir o objeto para o banco. Mais à
frente colocaremos esse código.
Caso você ache que o nome edit para esse método é meio enganoso quando um novo re-
gistro está sendo criado, você pode usar regras de roteamento genéricas para especificar que
invocações a ações chamadas create, update, e save são redirecionadas para a mesma ação
edit. Separar ou não as suas ações é um decisão que depende obviamente do que você está
fazendo no momento. A tendência com o uso de REST, inclusive, é de ações bem específicas,
que respondem a somente um tipo de verbo HTTP.
Agora que o nosso método começou a tomar forma, precisamos editar a view edit.html para
exibir o nosso formulário.
O arquivo presente está assim:
½ ÈÖÓ 
Ø× Ø » ½
Ô Ò Ñ Ò ÔÔ»Ú Û×»ÔÖÓ 
Ø×» ØºÖ ØÑÐ »Ô
Precisamos indicar ao usuário se estamos editando um registro existente ou adicionando um
novo registro no próprio cabeçalho da página. Para isso podemos usar o seguinte código:
½ ± ÔÖÓ 
ØºÒ Û Ö 
ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ 
Ø » ½
Note que estamos usando a variável @project que criamos no método edit. O @ indica uma
variável de instância, que o Rails automaticamente propaga para qualquer view sendo processada
a partir da ação em que a variável foi definida.
Na linha acima, estamos usando o método new_record?, presente em todas as classes de
dados derivadas do ActiveRecord para identificar se estamos lidando com um novo registro ou
com um registro já existente. Esse método retorna verdadeiro enquanto a classe não for salva
pela primeira vez. Com base nisso, exibimos o nosso cabeçalho.
Se você rodar a página, invocando diretamente a URL /projects/edit, verá que já temos algo
funcionando:
71
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 19
Obviamente, se você tentar usar um id qualquer você verá um erro a menos que tenha inserido
aquele registro no banco de dados. O próximo passo agora é criar o formulário de dados. Para
isso, vamos editar a nossa view:
½ ± ÔÖÓ 
ØºÒ Û Ö 
ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ 
Ø » ½
± ר ÖØ ÓÖÑ Ø 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ±
± Ò ÓÖÑ Ø ±
O método start_form_tag funciona de maneira muito similar o método link_to, explicado anterior-
mente. No caso acima, estamos gerado um formulário apontando para a ação edit e passando o
id do objeto que estamos usando, seja novo ou não.
Duas coisas são interessantes nesse chamada: primeiro, o Rails é inteligente o bastante para
perceber que você está passando o objeto como se fosse o seu id e gerar o código necessário au-
tomaticamente; segundo, caso o objeto não tenha sido salvo, o Rails suprimirá automaticamente
o id sem que você precise fazer qualquer teste.
O outro método chamado, end_form_tag, simplesmente gera o fechamento do elemento form
na página.
Com o cabeçalho do nosso formulário gerado, podemos agora criar campos para edição. Um
projeto possui um nome e um descrição. O primeiro atributo é um texto simples, de uma linha
72
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
somente, enquanto o segundo é um texto que pode ter múltiplas linhas. Editando o nosso arquivo,
teremos o seguinte:
½ ± ÔÖÓ 
ØºÒ Û Ö 
ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ 
Ø » ½
± ר ÖØ ÓÖÑ Ø 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ±
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø Ò Ñ Æ Ñ »Ð Ð Ö
± Ø ÜØ Ð ÔÖÓ 
Ø ¸ Ò Ñ ±
»Ô
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø ×
Ö ÔØ ÓÒ ×
Ö ÔØ ÓÒ »Ð Ð Ö
± Ø ÜØ Ö ÔÖÓ 
Ø ¸ ×
Ö ÔØ ÓÒ ¸ ÖÓÛ× ±
»Ô
± Ò ÓÖÑ Ø ±
Essa modificação nos dá o seguinte:
Figura 20
73
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Os métodos text_field e text_area são responsáveis pela geração dos elementos de formu-
lário vistos acima. O Rails possui dezenas desses métodos, capazes de gerar várias combina-
ções possíveis para os tipos de dados suportados automaticamente e permitir extensões se você
precisar de algo mais customizado. E você sempre pode gerar o seu código manualmente em
situações especiais.
Veja que cada método recebe um objeto e um atributo a ser gerado. No caso desses métodos,
você não precisa usar o @ diretamente: basta passar o nome do objeto e o método saberá
recuperá-lo do controller que está sendo executado.
Se você olhar o HTML gerado, verá o seguinte:
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø Ò Ñ Æ Ñ »Ð Ð Ö
ÒÔÙØ ÔÖÓ 
Ø Ò Ñ Ò Ñ ÔÖÓ 
Ø Ò Ñ ℄ × Þ ¿¼ ØÝÔ Ø ÜØ »
»Ô
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø ×
Ö ÔØ ÓÒ ×
Ö ÔØ ÓÒ »Ð Ð Ö
Ø ÜØ Ö 
ÓÐ× ¼ ÔÖÓ 
Ø ×
Ö ÔØ ÓÒ Ò Ñ ÔÖÓ 
Ø ×
Ö ÔØ ÓÒ℄ ÖÓÛ× »Ø ÜØ Ö
»Ô
Veja que os métodos geram um formato similar de elementos, criando atributos name e id
específicos para facilitar a vida do desenvolvedor. O atributo id pode ser associado a um elemento
label como demonstrado e o atributo name é o que é enviado ao Rails, gerando automaticamente
uma tabela hash dos dados submetidos pelo formulário que a ação pode usar. Dentro de um
controller você será capaz de usar params[:project] para acessar diretamente essa tabela hash,
como você verá adiante. O próximo passo, agora, é adicionar ações para salvar ou cancelar a
edição. Poderíamos ter algo assim:
½ ± ÔÖÓ 
ØºÒ Û Ö 
ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ 
Ø » ½
± ר ÖØ ÓÖÑ Ø 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ±
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø Ò Ñ Æ Ñ »Ð Ð Ö
± Ø ÜØ Ð ÔÖÓ 
Ø ¸ Ò Ñ ±
»Ô
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø ×
Ö ÔØ ÓÒ ×
Ö ÔØ ÓÒ »Ð Ð Ö
± Ø ÜØ Ö ÔÖÓ 
Ø ¸ ×
Ö ÔØ ÓÒ ¸ ÖÓÛ× ±
»Ô
Ô
± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò
 Ð ¸ 
Ø ÓÒ Ð ×Ø ±
»Ô
± Ò ÓÖÑ Ø ±
O formato acima é uma preferência de muitas aplicações Rails e reflete o fato de que a ação
para salvar deveria ser submetida pelo formulário enquanto a ação de cancelamento seria sim-
plesmente um retorno a um estado anterior. Mais do que isso, o método acima evita que tenha-
mos que descobrir qual botão foi pressionado em nosso formulário. Embora o código para isso
seja bem simples, repetí-lo em cada formulário se tornaria rapidamente tedioso, além de forçar
uma mistura de apresentação com lógica que queremos evitar a todo custo.
74
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Esse é um padrão que você verá repetidamente em aplicações atuais e que faz bastante
sentido do ponto de vista de usabilidade.
O resultado seria:
Figura 21
Temos agora um formulário completo funcionando. Precisamos simplesmente salvar o que
será submetido.
Voltando ao nosso controller, ficamos com o seguinte:

Ð ×× ÈÖÓ 
Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
Ò
Ø
Ô Ö Ñ× ℄
ÔÖÓ 
Ø ÈÖÓ 
غ Ò ´Ô Ö Ñ× ℄µ
75
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ð×
ÔÖÓ 
Ø ÈÖÓ 
ØºÒ Û
Ò
Ö ÕÙ ×ØºÔÓר
ÔÖÓ 
غ ØØÖ ÙØ × Ô Ö Ñ× ÔÖÓ 
Ø℄
ÔÖÓ 
Øº× Ú
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Ò
Ð Ø
Ò
Ò
Todo objeto que representa uma classe de dados no Rails possui um atributo chamado at-
tributes, que representa uma coleção das colunas da tabela equivalentes. Esse atributo aceita
receber uma tabela hash para preenchimento de seus valores. Como mencionado anteriormente,
é aqui que os dados gerados pelo Rails na submissão do formulário vem a calhar, servindo para
associação direta no objeto. Cada item existente em params[:project] no código acima, como,
por exemplo, params[:project][:name], preencherá seu item correspondente sem necessidade de
código adicional.
Continuando o código, tentamos salvar o objeto. Se isso tem sucesso (ou seja, se nenhuma
validação falha) redirecionamos para a página de listagem. Caso contrário, exibimos o formulá-
rio novamente. Nesse caso, note que o Rails usará a mesma view, seguindo o comportamento
padrão, efetivamente mostrando o formulário preenchido com os dados postados. Isso acontece
porque os métodos text_field e text_area (e os demais) preenchem automaticamente os elemen-
tos de formulário com os valores existentes no objeto que receberam. Isso torna a nossa tarefa
bem simples.
Se você tentar salvar um formulário sem preencher nada, verá o seguinte agora:
76
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 22
Notamos que a validação está funcionando, mas nenhum erro é exibido. Para isso, precisamos
da seguinte modificação em nossa view:
½ ± ÔÖÓ 
ØºÒ Û Ö 
ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ 
Ø » ½
± ÖÖÓÖ Ñ ×× × ÓÖ ÔÖÓ 
Ø ±
± ר ÖØ ÓÖÑ Ø 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ±
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø Ò Ñ Æ Ñ »Ð Ð Ö
± Ø ÜØ Ð ÔÖÓ 
Ø ¸ Ò Ñ ±
»Ô
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø ×
Ö ÔØ ÓÒ ×
Ö ÔØ ÓÒ »Ð Ð Ö
± Ø ÜØ Ö ÔÖÓ 
Ø ¸ ×
Ö ÔØ ÓÒ ¸ ÖÓÛ× ±
»Ô
Ô
± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò
 Ð ¸ 
Ø ÓÒ Ð ×Ø ±
»Ô
± Ò ÓÖÑ Ø ±
77
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
O que nos dá:
Figura 23
Se você salvar um objeto agora, verá que somos redirecionados para a ação list que ainda
precisamos criar. Uma listagem é algo bem simples e queremos exibir, inicialmente, somente o
nome do projeto. Para isto, vamos criar algo bem básico:
½ ÈÖÓ 
Ø× » ½
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø Æ Ñ »Ø
»ØÖ
»Ø Ð
Isso nos dá um tabela simples. Agora, queremos exibir os registros criados. Precisamos,
obviamente, buscar esses objetos no banco. Modificando o controller ficamos com algo assim:

Ð ×× ÈÖÓ 
Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
78
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
ÔÖÓ 
Ø× ÈÖÓ 
غ Ò Ðи ÓÖ Ö Ò Ñ
Ò
Ø
Ô Ö Ñ× ℄
ÔÖÓ 
Ø ÈÖÓ 
غ Ò ´Ô Ö Ñ× ℄µ
Ð×
ÔÖÓ 
Ø ÈÖÓ 
ØºÒ Û
Ò
Ö ÕÙ ×ØºÔÓר
ÔÖÓ 
غ ØØÖ ÙØ × Ô Ö Ñ× ÔÖÓ 
Ø℄
ÔÖÓ 
Øº× Ú
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Ò
Ð Ø
Ò
Ò
Uma variável chamada @projects receberá uma lista de todos projetos ordenados pelo atri-
buto name. O método find, já tratado anteriormente, recebe como primeiro parâmetro uma espe-
cificação do que retornar ou um id específico. No caso acima, queremos todos registros (all). O
segundo parâmetro, nomeado, recebe a especificação de ordenação.
Um detalhe da chamada acima. Muitas vezes, em código Ruby, você verá um seqüência de
parâmetros nomeados no fim de uma chamada. O Ruby não possui parâmetros nomeados em si,
mas é capaz de simular isso com o uso de uma tabela hash com último parâmetro de um método.
Quando um método usa essa técnica, o Ruby automaticamente permite que os parâmetros sejam
declarados de forma livre, pelo nome, e os combina no momento da chamada em uma tabela hash
que é então passada como parâmetro. Assim, o primeiro parâmetro do método find acima é um
símbolo e o segundo parâmetro é uma tabela hash cujo único elemento é um par definido por um
símbolo e uma string.
Agora, já podemos usar esses objetos em uma view:
½ ÈÖÓ 
Ø× » ½
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø Æ Ñ »Ø
»ØÖ
± ÔÖÓ 
Ø×º 
 Ó ÔÖÓ 
Ø ± Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø ± ÔÖÓ 
ØºÒ Ñ ± »Ø
»ØÖ
± Ò ±
»Ø Ð
79
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
No caso acima, o método find retorna um array que pode ou não conter itens.
Uma coisa a manter em mente aqui é que, para caso de uso desse método, o retorno pode ser
diferente. Se você estiver usando find com :first, o retorno será um objeto ou o valor nil. Se você
estiver passando um id específico, um objeto será retornado ou um erro será gerado. Lembre-se
disso sempre que usar o método em suas variações. As variações servem para cobrir as situa-
ções mais comuns, e você sempre pode escrever seus próprios métodos usando as combinações
acima para obter o resultado que deseja.
Com dois projetos inseridos, o resultado é:
Figura 24
Podemos agora modificar a nossa view para permitir algumas ações sobre esses objetos. Por
exemplo:
½ ÈÖÓ 
Ø× » ½
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø Æ Ñ »Ø
Ø 
Ø ÓÒ× »Ø
»ØÖ
80
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
± ÔÖÓ 
Ø×º 
 Ó ÔÖÓ 
Ø ±
ØÖ
Ø ± ÔÖÓ 
ØºÒ Ñ ± »Ø
Ø
± Ð Ò ØÓ Ø ¸ 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ± ÓÖ
± Ð Ò ØÓ Ð Ø ¸ 
Ø ÓÒ Ð Ø ¸ ÔÖÓ 
Ø ±
ȯ
»ØÖ
± Ò ±
»Ø Ð
Como você dever ter notado pelas chamadas a link_to na view acima e em outros pontos do
código já exibido, o Rails é capaz de derivar os elementos da uma URL dos parâmetros que estão
sendo usados no momento.
O resultado da aplicação da view acima é visto abaixo:
Figura 25
Clicando na edição de um dos itens acima, temos:
81
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 26
Como é possível ver, o cabeçalho da página mudou para indicar uma edição e os campos
já vieram preenchidos. Você já pode alterar cada objeto sem problemas. Precisamos agora de
refinar alguns aspectos de nosso controller.
Precisamos de um link para criar um novo registro. Isso é facilmente conseguido:
½ ÈÖÓ 
Ø× » ½
Ô ± Ð Ò ØÓ Æ Û ÈÖÓ 
Ø ¸ 
Ø ÓÒ Ø ± »Ô
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø Æ Ñ »Ø
Ø 
Ø ÓÒ× »Ø
»ØÖ
± ÔÖÓ 
Ø×º 
 Ó ÔÖÓ 
Ø ±
ØÖ
Ø ± ÔÖÓ 
ØºÒ Ñ ± »Ø
Ø
± Ð Ò ØÓ Ø ¸ 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ± ÓÖ
± Ð Ò ØÓ Ð Ø ¸ 
Ø ÓÒ Ð Ø ¸ ÔÖÓ 
Ø ±
82
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
ȯ
»ØÖ
± Ò ±
»Ø Ð
Um dos problemas em deixar que um registro seja removido com um simples invocação é
que o usuário não tem como reverter a ação. Podemos adicionar um mínimo de proteção com a
seguinte alteração:
½ ÈÖÓ 
Ø× » ½
Ô ± Ð Ò ØÓ Æ Û ÈÖÓ 
Ø ¸ 
Ø ÓÒ Ø ± »Ô
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø Æ Ñ »Ø
Ø 
Ø ÓÒ× »Ø
»ØÖ
± ÔÖÓ 
Ø×º 
 Ó ÔÖÓ 
Ø ±
ØÖ
Ø ± ÔÖÓ 
ØºÒ Ñ ± »Ø
Ø
± Ð Ò ØÓ Ø ¸ 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ± ÓÖ
± Ð Ò ØÓ Ð Ø ¸ ß 
Ø ÓÒ Ð Ø ¸ ÔÖÓ 
Ø ¸ 
ÓÒ ÖÑ Ö ÝÓÙ ×
ȯ
»ØÖ
± Ò ±
»Ø Ð
Note que, por estamos usando um terceiro parâmetro do método link_to, precisamos de adi-
cionar chaves ao redor do segundo para que o Ruby não exerça o seu comportamento padrão
e concatene todos os parâmetros livres em um só. No caso acima, tanto o segundo parâmetro
da chamada como o terceiro são tabelas hash, embora somente a segunda esteja explicitamente
indicada.
O resultado das modificações acima é o seguinte, como podemos ver ao clicar na ação para
remover o projeto:
83
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 27
A ação delete também pode ser protegida de acesso GET diretos com o uso de outra carac-
terística do Rails que é a transformação de links em formulários caso a ação seja bem simples.
O resultado visual não é muito interessante e você pode observá-lo no código do scaffold que foi
gerado anteriormente para o modelo de dados de contextos.
Vamos agora inserir a ação para excluir registros, que é bem simples:

Ð ×× ÈÖÓ 
Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
ÔÖÓ 
Ø× ÈÖÓ 
غ Ò Ðи ÓÖ Ö Ò Ñ
Ò
Ø
Ô Ö Ñ× ℄
ÔÖÓ 
Ø ÈÖÓ 
غ Ò ´Ô Ö Ñ× ℄µ
Ð×
84
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
ÔÖÓ 
Ø ÈÖÓ 
ØºÒ Û
Ò
Ö ÕÙ ×ØºÔÓר
ÔÖÓ 
غ ØØÖ ÙØ × Ô Ö Ñ× ÔÖÓ 
Ø℄
ÔÖÓ 
Øº× Ú
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Ò
Ð Ø
ÈÖÓ 
غ Ò ´Ô Ö Ñ× ℄µº רÖÓÝ
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Como essa ação não possui nenhuma view, o arquivo gerado delete.rhtml também pode ser
excluído.
Uma outra alteração que pode ser feita é a exibição de mensagens de dados para algumas
ações. Para isso, vamos usar uma outra característica dos Rails, as variáveis flash. Essas variá-
veis são similares a variáveis de sessão, mas somente persistem de uma página para outra. Uma
vez que a requisição para a qual foram propagadas acaba, elas são automaticamente removidas
do contexto de execução.
Vamos modificar nosso controller mais uma vez:

Ð ×× ÈÖÓ 
Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
ÔÖÓ 
Ø× ÈÖÓ 
غ Ò Ðи ÓÖ Ö Ò Ñ
Ò
Ø
Ô Ö Ñ× ℄
ÔÖÓ 
Ø ÈÖÓ 
غ Ò ´Ô Ö Ñ× ℄µ
Ð×
ÔÖÓ 
Ø ÈÖÓ 
ØºÒ Û
Ò
Ö ÕÙ ×ØºÔÓר
ÔÖÓ 
غ ØØÖ ÙØ × Ô Ö Ñ× ÔÖÓ 
Ø℄
ÔÖÓ 
Øº× Ú
Ð × ÒÓØ 
 ℄ Ì ÔÖÓ 
Ø Û × ×Ù

 ×× ÙÐÐÝ × Ú
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Ò
85
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ð Ø
ÈÖÓ 
غ Ò ´Ô Ö Ñ× ℄µº רÖÓÝ
Ð × ÒÓØ 
 ℄ Ì ÔÖÓ 
Ø Û × ×Ù

 ×× ÙÐÐÝ Ð Ø
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Podemos agora usar essas variáveis em nossa view para a ação list, que é para onde as duas
ações em questão retornam:
½ ÈÖÓ 
Ø× » ½
± Ð × ÒÓØ 
 ℄ ±
Ô ×ØÝÐ 
ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð 
 ± Ð × ÒÓØ 
 ℄ ± »Ô
± Ò ±
Ô ± Ð Ò ØÓ Æ Û ÈÖÓ 
Ø ¸ 
Ø ÓÒ Ø ± »Ô
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø Æ Ñ »Ø
Ø 
Ø ÓÒ× »Ø
»ØÖ
± ÔÖÓ 
Ø×º 
 Ó ÔÖÓ 
Ø ±
ØÖ
Ø ± ÔÖÓ 
ØºÒ Ñ ± »Ø
Ø
± Ð Ò ØÓ Ø ¸ 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ± ÓÖ
± Ð Ò ØÓ Ð Ø ¸ ß 
Ø ÓÒ Ð Ø ¸ ÔÖÓ 
Ø ¸ 
ÓÒ ÖÑ Ö ÝÓÙ ×Ù
ȯ
»ØÖ
± Ò ±
»Ø Ð
Uma pequena observação que cabe aqui é o uso de símbolos ao invés de strings na referên-
cia a tabelas hash. Símbolos são sempre uma forma de acesso mais interessante por apontarem
sempre para uma única instância e poderem ser otimizados pelo interpretador. O Rails geral-
mente permite as duas formas de acesso para suas variáveis internas representadas com tabelas
hash, mas é sempre bom escolher um dos métodos de acesso e manter um padrão em relação
ao mesmo. Isso facilita a legibilidade da aplicação e evita o aparecimento de erros proveniente
da mistura dos dois tipos de acesso.
O resultado é o seguinte, após uma ação de edição:
86
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 28
A variável flash[:notice] está disponível somente naquela requisição como você pode verificar
recarregando a página.
87
Capítulo 9
Extendendo um modelo de dados e
Helpers
Essa lição visa extender nosso modelo de dados para aproveitando o nosso controller. E
mostrar o que são os Helpers.
9.1 Extendendo um modelo de dados
Algo que podemos fazer agora, para aproveitar o nosso controller é extender o nosso modelo
de dados. Vamos dizer que precisamos saber se um projeto está ativo ou não. O nosso modelo
de dados não contém esse atributo, mas podemos gerar uma migração para isso.
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ» Ò Ö Ø Ñ Ö Ø ÓÒ ×Ø ØÙ× ØÓ ÔÖÓ 
Ø
Ü ×Ø× »Ñ Ö Ø

Ö Ø »Ñ Ö Ø »¼¼ ר ØÙ× ØÓ ÔÖÓ 
غÖ
Essa é uma migração um pouco diferente porque adiciona uma coluna a um modelo de dados.
Editando o arquivo da migração, teríamos algo assim:

Ð ×× ËØ ØÙ×ÌÓÈÖÓ 
Ø 
Ø Ú Ê 
ÓÖ Å Ö Ø ÓÒ
× Ð ºÙÔ

ÓÐÙÑÒ ÔÖÓ 
Ø×¸ 
Ø Ú ¸ ÓÓÐ Ò
ÈÖÓ 
ØºÖ × Ø 
ÓÐÙÑÒ Ò ÓÖÑ Ø ÓÒ
ÈÖÓ 
غÙÔ Ø ÐÐ 
Ø Ú ½
Ò
× Ð º ÓÛÒ
Ö ÑÓÚ 
ÓÐÙÑÒ ÔÖÓ 
Ø×¸ 
Ø Ú
Ò
Ò
Nesse caso, estamos adicionando uma coluna e automaticamente atualizando para um valor
que achamos mais indicado.
Como o nosso modelo está sendo modificado, precisamos usar o método reset_column_information
para que o Rails releia as tabelas e recarregue os modelos imediatamente. Na verdade, isso não
é estritamente necessário pelo uso do método update_all, mas é interessante saber que esse uso
pode ser necessário em alguns casos. O método update_all atualiza todos os registros usando o
88
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
fragmento de SQL passado como parâmetro., pulando quaisquer validações existentes?portanto,
use-o com cuidado.
Após rodar o comando rake db:migrate, veremos o nosso banco atualizado completamente.
Note que, nesse caso, a migração para um versão anterior simplesmente remove a coluna.
9.2 Usando Helpers
Helpers são classes associadas a cada controller que contém funções utilitárias que são auto-
maticamente exportadas para as views associadas ao mesmo. Cada controller tem o seu próprio
helper e, a exemplo dos controllers, todos os helpers herdam métodos de uma classe base, que
está definida no arquivo app/helpers/application_helper.rb. Olhando no diretório desse arquivo
você pode ver que para cada controller, um helper já foi gerado.
Precisamos de um método que receba um valor booleano e retorne um representação hu-
mana disso. Como talvez precisemos usar esse método em outras views que não as da classe
de projetos, seria mais interessante inserir o método no helper global da aplicação, modificando
o arquivo application_helper.rb presente no diretório app/helpers. Teríamos, então, algo assim:
ÑÓ ÙÐ ÔÔÐ 
 Ø ÓÒÀ ÐÔ Ö
Ý × ÓÖ ÒÓ ´Ú ÐÙ µ
Ú ÐÙ × ÆÓ
Ò
Ò
O método yes_or_no? está agora disponível para qualquer view na aplicação. Vamos usá-lo,
modificando a nossa view:
½ ÈÖÓ 
Ø× » ½
± Ð × ÒÓØ 
 ℄ ±
Ô ×ØÝÐ 
ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð 
 ± Ð × ÒÓØ 
 ℄ ± »Ô
± Ò ±
Ô ± Ð Ò ØÓ Æ Û ÈÖÓ 
Ø ¸ 
Ø ÓÒ Ø ± »Ô
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø Æ Ñ »Ø
Ø 
Ø Ú »Ø
Ø 
Ø ÓÒ× »Ø
»ØÖ
± ÔÖÓ 
Ø×º 
 Ó ÔÖÓ 
Ø ±
ØÖ
Ø ± ÔÖÓ 
ØºÒ Ñ ± »Ø
Ø ± Ý × ÓÖ ÒÓ ´ÔÖÓ 
غ 
Ø Ú µ ± »Ø
Ø
± Ð Ò ØÓ Ø ¸ 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ± ÓÖ
± Ð Ò ØÓ Ð Ø ¸ ß 
Ø ÓÒ Ð Ø ¸ ÔÖÓ 
Ø ¸ 
ÓÒ ÖÑ Ö ÝÓÙ ×Ù
ȯ
»ØÖ
± Ò ±
»Ø Ð
89
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Note que podemos agora chamar o método definido no helper e também que temos um novo
atributo na classe.
Uma convenção especial do Rails é que, se um atributo representar um valor booleano, você
pode acrescentar um ponto de interrogação após o método para que ele retorne verdadeiro ou
falso diretamente. Isso acontece porque nem todos bancos de dados possuem campos boolea-
nos nativos por padrão. No caso do MySQL, por exemplo, valores booleanos são representados
por campos inteiros contendo zero ou um. O uso da interrogação facilita a visualização e uso do
campo.
Em várias situações, o Rails é capaz de detectar automaticamente o valor booleano, e o ponto
de interrogação não é estritamente necessário. Mas é uma boa convenção fazer isso. Não só o
código fica mais legível de imediato, como qualquer desenvolvedor Rails será capaz de dizer o
tipo de dados armazenado no campo.
O resultado agora é:
Figura 29
Obviamente, precisamos editar o fato do projeto estar ativo ou não. Vamos alterar nossa view
de edição:
½ ± ÔÖÓ 
ØºÒ Û Ö 
ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ 
Ø » ½
90
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
± ÖÖÓÖ Ñ ×× × ÓÖ ÔÖÓ 
Ø ±
± ר ÖØ ÓÖÑ Ø 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ±
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø Ò Ñ Æ Ñ »Ð Ð Ö
± Ø ÜØ Ð ÔÖÓ 
Ø ¸ Ò Ñ ±
»Ô
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø ×
Ö ÔØ ÓÒ ×
Ö ÔØ ÓÒ »Ð Ð Ö
± Ø ÜØ Ö ÔÖÓ 
Ø ¸ ×
Ö ÔØ ÓÒ ¸ ÖÓÛ× ±
»Ô
Ô
Ð Ð ÓÖ ÔÖÓ 
Ø 
Ø Ú 
Ø Ú »Ð Ð Ö
± × Ð 
Ø ÔÖÓ 
Ø ¸ 
Ø Ú ¸ × ¸ ØÖÙ ℄¸ ÆÓ ¸ Ð× ℄℄ ±
»Ô
Ô
± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò
 Ð ¸ 
Ø ÓÒ Ð ×Ø ±
»Ô
± Ò ÓÖÑ Ø ±
Essa é uma das maneiras de editar o atributo, usando um elemento select.
O método select gera automaticamente o código HTML necessário, recebendo parâmetros
similares aos outros métodos e uma lista de valores a serem usados como escolhas. Esses
valores são informados como um array de arrays onde cada item representa um par, contendo a
descrição e o valor a ser atribuído. No caso acima, temos descrições Yes e No, correspondendo
a valores true e false.
O Rails define uma série de outros métodos capaz de gerar elementos select. Alguns des-
ses métodos são especializados em gerar coleções aninhadas, por exemplo, enquanto outros
geram diversos formatos de data. Antes de experimentar o método genérico acima, consulte a
documentação para ver se existe algum método que lhe atenda.
Lembre-se que, para valores booleanos, para que a atribuição funcione automaticamente, os
valores true e false devem ser necessariamente usados. Caso contrário, a conversão automática
de tipos do Ruby entra em ação e os dados não são processados apropriamente.
O resultado pode ser visto abaixo e testando você verá que ele funciona perfeitamente, alte-
rando os valores de acordo com sua escolha sem necessidade de qualquer codificação adicional:
91
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 30
Existem pelo menos duas outras diretas maneiras de fazer a edição de um valor booleano.
Uma seria usando radio buttons e checkboxes. Testar essas maneiras fica como um exercício
para o leitor, lembrando que o princípio é o mesmo.
Uma última coisa seria modificar o controller para gerar paginação automática. Isso é facil-
mente conseguido com duas atualizações.
Uma no controller:

Ð ×× ÈÖÓ 
Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
ÔÖÓ 
Ø Ô ×¸ ÔÖÓ 
Ø× Ô Ò Ø ÔÖÓ 
Ø×¸ Ô Ö Ô ¸ ÓÖ Ö Ò Ñ
Ò
Ø
Ô Ö Ñ× ℄
ÔÖÓ 
Ø ÈÖÓ 
غ Ò ´Ô Ö Ñ× ℄µ
92
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ð×
ÔÖÓ 
Ø ÈÖÓ 
ØºÒ Û
Ò
Ö ÕÙ ×ØºÔÓר
ÔÖÓ 
غ ØØÖ ÙØ × Ô Ö Ñ× ÔÖÓ 
Ø℄
ÔÖÓ 
Øº× Ú
Ð × ÒÓØ 
 ℄ Ì ÔÖÓ 
Ø Û × ×Ù

 ×× ÙÐÐÝ × Ú
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Ò
Ð Ø
ÈÖÓ 
غ Ò ´Ô Ö Ñ× ℄µº רÖÓÝ
Ð × ÒÓØ 
 ℄ Ì ÔÖÓ 
Ø Û × ×Ù

 ×× ÙÐÐÝ Ð Ø
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
E outra na view:
½ ÈÖÓ 
Ø× » ½
± Ð × ÒÓØ 
 ℄ ±
Ô ×ØÝÐ 
ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð 
 ± Ð × ÒÓØ 
 ℄ ± »Ô
± Ò ±
Ô ± Ð Ò ØÓ Æ Û ÈÖÓ 
Ø ¸ 
Ø ÓÒ Ø ± »Ô
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø Æ Ñ »Ø
Ø 
Ø Ú »Ø
Ø 
Ø ÓÒ× »Ø
»ØÖ
± ÔÖÓ 
Ø×º 
 Ó ÔÖÓ 
Ø ±
ØÖ
Ø ± ÔÖÓ 
ØºÒ Ñ ± »Ø
Ø ± Ý × ÓÖ ÒÓ ´ÔÖÓ 
غ 
Ø Ú µ ± »Ø
Ø
± Ð Ò ØÓ Ø ¸ 
Ø ÓÒ Ø ¸ ÔÖÓ 
Ø ± ÓÖ
± Ð Ò ØÓ Ð Ø ¸ ß 
Ø ÓÒ Ð Ø ¸ ÔÖÓ 
Ø ¸ 
ÓÒ ÖÑ Ö ÝÓÙ ×Ù
ȯ
»ØÖ
± Ò ±
»Ø Ð
Ô ± Ô Ò Ø ÓÒ Ð Ò ×´ÔÖÓ 
Ø Ô ×µ ± »Ô
A modificação no controller usa um método que já mencionamos anteriormente, paginate,
para encapsular o processo de paginar os registros e gerar uma listagem de páginas (aqui sepa-
radas em cinco registros por página). A modificação na view, por sua vez, simplesmente cria uma
lista de páginas com base na informação retornada pelo método de paginação.
93
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Os métodos usados são razoavelmente simples, mas, infelizmente, estão entre dois dos mais
ineficientes do Rails e devem ser usados com cuidado. No momento, entretando, com a quan-
tidade de dados que temos, eles não chegam a representar um problema. O resultado depois
pode ser visto abaixo.
Visualizando a primeira página, temos:
Figura 31
E em seguida, a segunda página (note o parâmetro adicional da URL):
94
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 32
Terminamos um controller completo - simples, mas funcional - e, inclusive, alteramos o modelo
de dados por trás do mesmo de acordo com nossa necessidade.
Agora já temos uma base para investigarmos o próximo passo de uma aplicação: relaciona-
mentos entre classes de dados.
95
Capítulo 10
Relacionamentos
Essa lição tem como objetivo mostrar o que são relacionamentos.
10.1 Início
Antes de começarmos a ver os relacionamentos, vamos unir o nosso projeto sob um layout
que pelo menos nos permita navegar mais facilmente. Nosso novo arquivo app/views/layouts/application.rb
ficaria assim:
ØÑÐ
Ø ØÐ Ì »Ø ØÐ
± רÝÐ × Ø Ð Ò Ø ÙÐØ ±
± רÝÐ × Ø Ð Ò Ø ×
 ÓÐ ±
»
Ó Ý
½ Ö Ì » ½
ÙÐ Ñ ÒÙ
Ð ± Ð Ò ØÓ ÙÒÐ ×× 
ÙÖÖ ÒØ ²Ö ÕÙÓ ÓÒØ ÜØ× ¸ 
ÓÒØÖÓÐÐ Ö 
ÓÒØ ÜØ× ± »Ð
Ð ± Ð Ò ØÓ ÙÒÐ ×× 
ÙÖÖ ÒØ ²Ö ÕÙÓ ÈÖÓ 
Ø× ¸ 
ÓÒØÖÓÐÐ Ö ÔÖÓ 
Ø× ± »Ð
»ÙÐ
Ú 
ÓÒØ ÒØ× ± Ý Ð ± » Ú
» Ó Ý
» ØÑÐ
E a stylesheet que estamos usando, default.css, dessa maneira:
Ó Ý
ß
ÓÒØ¹ Ñ ÐÝ Î Ö Ò ¸ Ö Ð¸ × Ò×¹× Ö
ÓÒØ¹× Þ ½¼¼±
Ñ Ö Ò ¼
Ô Ò ¼
½ Ö
ß
96
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF

 ÖÓÙÒ ¹
ÓÐÓÖ 



ÓÐÓÖ Û Ø
Ô Ò ½¼ÔÜ ½¼ÔÜ ½ ÔÜ
Ñ Ö Ò ¼
ÙÐ Ñ ÒÙ
ß
Ô Ò ÔÜ ½¼ÔÜ
Ñ Ö Ò ¼
ÓÖ Ö¹ ÓØØÓÑ ½ÔÜ ×ÓÐ 


ÙÐ Ñ ÒÙ Ð
ß
×ÔÐ Ý ÒÐ Ò
Ñ Ö Ò¹Ö Ø ÔÜ
ÓÒØ¹Û Ø ÓÐ
ÙÐ Ñ ÒÙ
ß
Ø ÜØ¹ 
ÓÖ Ø ÓÒ ÒÓÒ
ÓÒØ¹Û Ø ÒÓÖÑ Ð
Ú 
ÓÒØ ÒØ×
ß
Ñ Ö Ò ½¼ÔÜ
Ú 
ÓÒØ ÒØ× ½
ß
ÓÒØ¹× Þ ½¿¼±
ÓÒØ¹×ØÝÐ Ø Ð 
O resultado final seria:
97
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 33
Não é perfeito por causa de alguns defeitos no código HTML (como o uso de dois elementos
H1 na página, tabelas com estilos aplicados diretamente, etc) e pelo uso da stylesheet scaf-
fold.css, mas já é uma melhoria (desconsiderando, é claro, o fato de que eu não entendo nada
de design gráfico). Modificações do primeiro scaffold gerado para contextos ficam como um exer-
cício para o leitor. O objetivo é demonstrar como podemos atualizar a aplicação sem mexer em
qualquer dos controllers e views posteriormente geradas uma vez que elas tenham sido bem
planejadas.
Para exemplificarmos os relacionamentos, vamos começar com o cadastro de ações. Uma
ação pertence a um projeto e é executado em um determinado contexto. Isso é suficiente para
começarmos o nosso cadastro. Atualizamos primeiro o arquivo application.rhtml para incluir a
nossa nova área, temos:
ØÑÐ
Ø ØÐ Ì »Ø ØÐ
± רÝÐ × Ø Ð Ò Ø ÙÐØ ±
± רÝÐ × Ø Ð Ò Ø ×
 ÓÐ ±
»
98
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ó Ý
½ Ö Ì » ½
ÙÐ Ñ ÒÙ
Ð ± Ð Ò ØÓ ÙÒÐ ×× 
ÙÖÖ ÒØ ²Ö ÕÙÓ ÓÒØ ÜØ× ¸ 
ÓÒØÖÓÐÐ Ö 
ÓÒØ ÜØ× ¸ 
Ø ÓÒ
Ð ± Ð Ò ØÓ ÙÒÐ ×× 
ÙÖÖ ÒØ ²Ö ÕÙÓ ÈÖÓ 
Ø× ¸ 
ÓÒØÖÓÐÐ Ö ÔÖÓ 
Ø× ¸ 
Ø ÓÒ
Ð ± Ð Ò ØÓ ÙÒÐ ×× 
ÙÖÖ ÒØ ²Ö ÕÙÓ 
Ø ÓÒ× ¸ 
ÓÒØÖÓÐÐ Ö 
Ø ÓÒ× ¸ 
Ø ÓÒ Ð
»ÙÐ
Ú 
ÓÒØ ÒØ× ± Ý Ð ± » Ú
» Ó Ý
» ØÑÐ
Em segundo lugar, geramos o nosso controller. Vamos seguir o mesmo estilo do controller
usado para projetos:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ» Ò Ö Ø 
ÓÒØÖÓÐÐ Ö 
Ø ÓÒ× Ò Ü Ð ×Ø Ø Ð Ø
Ü ×Ø× ÔÔ»
ÓÒØÖÓÐÐ Ö×»
Ü ×Ø× ÔÔ» ÐÔ Ö×»

Ö Ø ÔÔ»Ú Û×» 
Ø ÓÒ×
Ü ×Ø× Ø ×Ø» ÙÒ
Ø ÓÒ Ð»

Ö Ø ÔÔ»
ÓÒØÖÓÐÐ Ö×» 
Ø ÓÒ× 
ÓÒØÖÓÐÐ ÖºÖ

Ö Ø Ø ×Ø» ÙÒ
Ø ÓÒ Ð» 
Ø ÓÒ× 
ÓÒØÖÓÐÐ Ö Ø ×ØºÖ

Ö Ø ÔÔ» ÐÔ Ö×» 
Ø ÓÒ× ÐÔ ÖºÖ

Ö Ø ÔÔ»Ú Û×» 
Ø ÓÒ×» Ò ÜºÖ ØÑÐ

Ö Ø ÔÔ»Ú Û×» 
Ø ÓÒ×»Ð ×ØºÖ ØÑÐ

Ö Ø ÔÔ»Ú Û×» 
Ø ÓÒ×» ØºÖ ØÑÐ

Ö Ø ÔÔ»Ú Û×» 
Ø ÓÒ×» Ð Ø ºÖ ØÑÐ
Para facilitar, vamos duplicar a funcionalidade presente no cadastro de projetos. O nosso
controller de ações ficaria assim, inicialmente:

Ð ×× 
Ø ÓÒ× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
 
Ø ÓÒ Ô ×¸  
Ø ÓÒ× Ô Ò Ø 
Ø ÓÒ׸ Ô Ö Ô ¸ ÓÖ Ö ×
Ö ÔØ ÓÒ
Ò
Ø
Ô Ö Ñ× ℄
 
Ø ÓÒ 
Ø ÓÒº Ò ´Ô Ö Ñ× ℄µ
Ð×
 
Ø ÓÒ 
Ø ÓÒºÒ Û
Ò
Ö ÕÙ ×ØºÔÓר
 
Ø ÓÒº ØØÖ ÙØ × Ô Ö Ñ× 
Ø ÓÒ℄
 
Ø ÓÒº× Ú
Ð × ÒÓØ 
 ℄ Ì 
Ø ÓÒ Û × ×Ù

 ×× ÙÐÐÝ × Ú
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
99
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ò
Ò
Ò
Ð Ø

Ø ÓÒº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ
Ð × ÒÓØ 
 ℄ Ì 
Ø ÓÒ Û × ×Ù

 ×× ÙÐÐÝ Ð Ø
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Seguido por nossa view de listagem, que ficaria assim:
½ 
Ø ÓÒ× » ½
± Ð × ÒÓØ 
 ℄ ±
Ô ×ØÝÐ 
ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð 
 ± Ð × ÒÓØ 
 ℄ ± »Ô
± Ò ±
Ô ± Ð Ò ØÓ Æ Û 
Ø ÓÒ ¸ 
Ø ÓÒ Ø ± »Ô
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø ×
Ö ÔØ ÓÒ »Ø
Ø ÓÒ »Ø
Ø 
Ø ÓÒ× »Ø
»ØÖ
±  
Ø ÓÒ׺ 
 Ó 
Ø ÓÒ ±
ØÖ
Ø ± 
Ø ÓÒº ×
Ö ÔØ ÓÒ ± »Ø
Ø ± Ý × ÓÖ ÒÓ ´ 
Ø ÓÒº ÓÒ µ ± »Ø
Ø
± Ð Ò ØÓ Ø ¸ 
Ø ÓÒ Ø ¸ 
Ø ÓÒ ± ÓÖ
± Ð Ò ØÓ Ð Ø ¸ ß 
Ø ÓÒ Ð Ø ¸ 
Ø ÓÒ ¸ 
ÓÒ ÖÑ Ö ÝÓÙ ×ÙÖ
ȯ
»ØÖ
± Ò ±
»Ø Ð
Ô ± Ô Ò Ø ÓÒ Ð Ò ×´ 
Ø ÓÒ Ô ×µ ± »Ô
Em, por fim, da nossa view de edição, que seria:
½ ±  
Ø ÓÒºÒ Û Ö 
ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± 
Ø ÓÒ » ½
± ÖÖÓÖ Ñ ×× × ÓÖ 
Ø ÓÒ ±
± ר ÖØ ÓÖÑ Ø 
Ø ÓÒ Ø ¸  
Ø ÓÒ ±
Ô
Ð Ð ÓÖ 
Ø ÓÒ ×
Ö ÔØ ÓÒ ×
Ö ÔØ ÓÒ »Ð Ð Ö
± Ø ÜØ Ö 
Ø ÓÒ ¸ ×
Ö ÔØ ÓÒ ¸ ÖÓÛ× ±
»Ô
Ô
Ð Ð ÓÖ 
Ø ÓÒ ÓÒ ÓÒ »Ð Ð Ö
± × Ð 
Ø 
Ø ÓÒ ¸ ÓÒ ¸ × ¸ ØÖÙ ℄¸ ÆÓ ¸ Ð× ℄℄ ±
»Ô
100
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ô
± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò
 Ð ¸ 
Ø ÓÒ Ð ×Ø ±
»Ô
± Ò ÓÖÑ Ø ±
Não tente usar essa view para salvar uma ação ainda. Há um erro sutil na mesma que discu-
tiremos mais adiante. As demais views geradas (index.rhtml e delete.rhtml) podem ser removidas
da aplicação pois não serão usadas.
Obviamente, a view acima não inclui todos os atributos presentes na ação. Para incluirmos
esses atributos, vamos considerar algumas coisas.
O atributos created_at representa a data de criação da ação. Atributos terminados em _at e
_on são automaticamente reconhecidos pelo Rails como representando datas e tempos, respec-
tivamente. Além disso, atributos com os nomes created_at, created_on, updated_at e update_on
serão automaticamente atualizados pelo Rails de acordo com a necessidade. Todos quando o
objeto for criado e os dois últimos sempre que o objeto for salvo.
Como o Rails obviamente não tem controle sobre o banco de dados, o desenvolvedor é que
deve escolher o tipo de dados certo para os mesmos no banco, usando date no caso dos termina-
dos em _at e datetime no caso dos terminados em _on (tipos de dados do MySQL, é claro-adapte
conforme a necessidade). Apesar disso, usar um tipo mais ou menos preciso não causa erros e
Rails tentará conversões sempre que necessário.
No nosso caso, então, não precisamos dar qualquer valor ao atributo created_at para que
ele seja salvo. Na verdade, como esse é um campo que deveria ser salvo uma única vez, vamos
colocar alguma informação no modelo para que o mesmo não possa ser atribuído em formulários,
mas somente em código direto.

Ð ×× 
Ø ÓÒ 
Ø Ú Ê 
ÓÖ ×
ØØÖ ÔÖÓØ 
Ø 
Ö Ø Ø
Ò
Esse declaração impede que esse atributo seja atualizado automaticamente por qualquer
atribuição via formulários ou métodos provindos do servidor. Somente uma atualização direta via
código funcionará e como não precisamos disso, não temos que nos preocupar mais com esse
atributo. O reverso dessa declaração seria attr_accessible.
O atributo completed_at representa a data em que a ação foi completada. Também não pre-
cisamos editá-lo em nossa view, já que ele poderia ser atribuído quando o usuário marcasse a
ação como completada. Faremos então a mesma coisa com esse atributo, mudando o nosso
modelo para:

Ð ×× 
Ø ÓÒ 
Ø Ú Ê 
ÓÖ ×
ØØÖ ÔÖÓØ 
Ø 
Ö Ø Ø¸ 
ÓÑÔÐ Ø Ø
Ò
Como o campo é atribuído automaticamente, o que precisamos fazer é achar alguma forma
de modificar esse atributo quando o atributo done, que representa o fato da ação estar completa,
for marcado como verdadeiro. A solução é sobrescrever o método de escrita do atributo done,
algo que o Rails permite justamente para esse tipo de situação:

Ð ×× 
Ø ÓÒ 
Ø Ú Ê 
ÓÖ ×
ØØÖ ÔÖÓØ 
Ø 
Ö Ø Ø¸ 
ÓÑÔÐ Ø Ø
101
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
ÓÒ ´Ú ÐÙ µ

Ø Ú Ê 
ÓÖ ÓÒÒ 
Ø ÓÒ ÔØ Ö× ÓÐÙÑÒºÚ ÐÙ ØÓ ÓÓÐ Ò´Ú ÐÙ µ
× Ð º
ÓÑÔÐ Ø Ø Ø Ì Ñ ºÒÓÛ
Ð×
× Ð º
ÓÑÔÐ Ø Ø Ò Ð
Ò
ÛÖ Ø ØØÖ ÙØ ´ ÓÒ ¸ Ú ÐÙ µ
Ò
Ò
Aqui, estamos usando o momento em que o atributo done é recebido e executando ações
extras. Note o sinal de igual, indicando que esse é um método de atribuição; no Ruby, qualquer
método terminado com o sinal pode ser automaticamente usado como se fosse um atributo. O
método verifica se valor recebido foi verdadeiro usando um método interno do ActiveRecord.
Essa chamada é necessária porque, exceto por nil e false, qualquer outro valor é considerado
verdadeiro em Ruby, incluindo zero e strings vazias. Se sim, o atributo completed_at é atualizado
com a data atual. Se não, o atributo é retornado a um valor nulo. Depois disso, o valor recebido
para o atributo done é passado sem modificações para a camada de banco de dados, usando o
método write_attribute.
Mesmo que você não precise modificar campos em dependência um do outro, a técnica acima
é util para guardar valores convertidos (por exemplo, um valor que é informado em graus, mas
armazenado em radianos ou vice-versa). O par de métodos write_attribute/read_attribute pode
ser usado em conjunção com métodos que sobrescrevem os métodos de acesso que o Rails gera
para permitir maior flexibilidade da manipulação de dados.
Finalmente, temos os atributos context_id e project_id, que representam as chaves estran-
geiras que criamos no banco, que usaremos para os nossos primeiros relacionamentos entre
classes.
102
Capítulo 11
Belongs to
Nessa lição falaremos de Belongs to.
11.1 Belongs to
No caso desses dois atributos, poderíamos dizer que uma ação pertence a um contexto e que
pertence a um projeto. No Rails, representaríamos isso da seguinte forma:

Ð ×× 
Ø ÓÒ 
Ø Ú Ê 
ÓÖ ×
ØØÖ ÔÖÓØ 
Ø 
Ö Ø Ø¸ 
ÓÑÔÐ Ø Ø
ÓÒ ´Ú ÐÙ µ

Ø Ú Ê 
ÓÖ ÓÒÒ 
Ø ÓÒ ÔØ Ö× ÓÐÙÑÒºÚ ÐÙ ØÓ ÓÓÐ Ò´Ú ÐÙ µ
× Ð º
ÓÑÔÐ Ø Ø Ø Ì Ñ ºÒÓÛ
Ð×
× Ð º
ÓÑÔÐ Ø Ø Ò Ð
Ò
ÛÖ Ø ØØÖ ÙØ ´ ÓÒ ¸ Ú ÐÙ µ
Ò
ÐÓÒ × ØÓ 
ÓÒØ ÜØ
ÐÓÒ × ØÓ ÔÖÓ 
Ø
Ò
Essas duas declarações são suficientes para criar uma série de facilidades no Rails que inclui
atribuições e buscas. Veja que você não precisou dizer nada sobre relacionamento além do que
ele referencia. O Rails é capaz de deduzir a chave estrangeira quando ela for criada concate-
nando o nome da tabela pai ao sufixo _id. Caso você tenha dado outro nome, você pode também
dizer ao Rails qual seria a chave estrangeira usando algo assim:
ÐÓÒ × ØÓ ×Ù 
ظ ÓÖ Ò Ý 
 Ø ÓÖÝ
Além dessa possibilidade, há outras opções na definição de um relacionamento que valem a
pena ser exploradas na documentação, incluindo outras condições limítrofes para o mesmo.
Para cada relacionamento criado, o Rails disponibiliza métodos que permitem testar a exis-
tência de uma associação, defini-la, removê-la e buscá-la. Vamos usar o console para testar
isso:
103
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ»
ÓÒ×ÓÐ
ÄÓ Ò Ú ÐÓÔÑ ÒØ ÒÚ ÖÓÒÑ ÒØº

Ø ÓÒ 
Ø ÓÒº
Ö Ø ´ ×
Ö ÔØ ÓÒ Ø ×Ø 
Ø ÓÒº µ

Ø ÓÒ ¼Ü ¿ ¿
 Ò Û Ö 
ÓÖ Ð× ¸  ÖÖÓÖ× 
Ø Ú Ê 
ÓÖ ÖÖÓÖ× ¼Ü ¾ ¼
 × 
Ø ÓÒ ¼Ü ¿ ¿
 ººº ¸  ÖÖÓÖ× ß ¸  ØØÖ ÙØ × ß 
ÓÒØ ÜØ Ò Ð¸ 
ÓÑÔÐ Ø Ø
ÔÖÓ 
Ø Ò Ð¸ ÓÒ Ò Ð¸ ¸ ×
Ö ÔØ ÓÒ Ø ×Ø 
Ø ÓÒº ¸ 
Ö Ø Ø Ì Ù Ë
½ ¾ ¿ ÊÌ ¾¼¼
Ì ÑÓ× ÙÑ Ó × ÐÚ º

Ø ÓÒºÔÖÓ 
Ø
Ò Ð

Ø ÓÒº
ÓÒØ ÜØ
Ò Ð

Ø ÓÒºÔÖÓ 
Ø
Ò Ð

Ø ÓÒº
ÓÒØ ÜØ
Ò Ð
Com o relacionamento, em adição aos atributos vindos do banco de dados temos agora outros
dois atributos que representam a relação.
Podemos atribui-los normalmente:

Ø ÓÒº
ÓÒØ ÜØ ½
½

Ø ÓÒº
ÓÒØ ÜØ
ÓÒØ ÜØ ¼Ü  ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½
Ou usar diretamente a relação:

Ø ÓÒºÔÖÓ 
Ø ÈÖÓ 
غ Ò ´½µ
ÈÖÓ 
Ø ¼Ü ¾  ØØÖ ÙØ × ß Ò Ñ Ù Ð ÀÓÙ× ¸ ½ ¸ ×
Ö ÔØ ÓÒ Ù Ð
Ö Ñ ÓÙ× ÒØ Ö ÐÝ ÔÐ ÒÒ Ý ÑÝ× Ð ¸ Ò
ÐÙ Ò ÒØ Ö ×Ø Ò ØØ 
 Û Ø Ù Ð Ö Öݺ ¸

Ø Ú ½

Ø ÓÒºÔÖÓ 
Ø
½
Se quisermos, podemos criar também novos valores diretamente:

Ø ÓÒº
ÓÒØ ÜØ ÓÒØ ÜØº
Ö Ø ´ Ò Ñ È ÓÒ µ
ÓÒØ ÜØ ¼Ü ½ ¼ Ò Û Ö 
ÓÖ Ð× ¸  ÖÖÓÖ× 
Ø Ú Ê 
ÓÖ ÖÖÓÖ× ¼Ü 
 × ÓÒØ ÜØ ¼Ü ½ ¼ ººº ¸  ÖÖÓÖ× ß ¸  ØØÖ ÙØ × ß Ò Ñ È ÓÒ ¸ ¿
Relacionamentos são bem úteis, mas precisamos ter um pouco de cuidado em como os usa-
mos. Aqui entra a necessidade de conhecimento de SQL que mencionamos anteriormente. Veja
o caso abaixo, por exemplo:

Ø ÓÒº Ò ´ µºÔÖÓ 
ØºÒ Ñ
Ù Ð ÀÓÙ×
104
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Se executarmos a ação acima e e observamos o log de desenvolvimento gerado pelo Rails
(que está em log/development.log), veremos o seguinte:

Ø ÓÒ ÄÓ ´¼º¼¼¾ ½µ Ë Ä Ì ¶ ÊÇÅ 
Ø ÓÒ× ÏÀ Ê ´ 
Ø ÓÒ׺ µ ÄÁÅÁÌ ½
ÈÖÓ 
Ø ÄÓ ´¼º¼¼½¾ µ Ë Ä Ì ¶ ÊÇÅ ÔÖÓ 
Ø× ÏÀ Ê ´ÔÖÓ 
Ø×º ½µ ÄÁÅÁÌ ½
Isso mostra que duas chamadas foram feitas ao banco para carregar o nome do projeto da
ação buscada, uma delas completamente desnecessária. Obviamente, se fizermos isso em um
loop, com múltiplos objetos e relacionamentos, o nível de ineficiência subirá rapidamente.
Para isso, o Rails tem uma solução que resolve a maior parte dos problemas causados por
isso, gerando joins automaticamente de acordo com o que o usuário precisa.
Por exemplo:

Ø ÓÒº Ò ´ ¸ Ò
ÐÙ ÔÖÓ 
ظ 
ÓÒØ ÜØ℄µ

Ø ÓÒ ¼Ü ¼ 
ÓÒØ ÜØ ÓÒØ ÜØ ¼Ü ½  ØØÖ ÙØ × ß Ò Ñ È ÓÒ ¸ ¿
ÔÖÓ 
Ø ÈÖÓ 
Ø ¼Ü  ØØÖ ÙØ × ß Ò Ñ Ù Ð ÀÓÙ× ¸ ½ ¸ ×
Ö ÔØ ÓÒ
Ö Ñ ÓÙ× ÒØ Ö ÐÝ ÔÐ ÒÒ Ý ÑÝ× Ð ¸ Ò
ÐÙ Ò ÒØ Ö ×Ø Ò ØØ 
 Û Ø Ù Ð Ö Öݺ

Ø Ú ½ ¸  ØØÖ ÙØ × ß 
ÓÒØ ÜØ ¿ ¸ 
ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ 
Ø ½ ¸ ÓÒ
¸ ×
Ö ÔØ ÓÒ Ø ×Ø 
Ø ÓÒº ¸ 
Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¾ ¿
Como você pode ver, tanto o contexto como o projeto foram automaticamente recuperados.
Se observamos o log, veremos o seguinte:

Ø ÓÒ ÄÓ ÁÒ
ÐÙ Ò ××Ó
 Ø ÓÒ× ´¼º¾¿¾¼ ¾µ Ë Ä Ì 
Ø ÓÒ׺ Ë Ø¼ Ö¼¸ 
Ø ÓÒ׺ ×
Ë Ø¼ Ö½¸ 
Ø ÓÒ׺ ÓÒ Ë Ø¼ Ö¾¸ 
Ø ÓÒ׺ 
Ö Ø Ø Ë Ø¼ Ö¿¸ 
Ø ÓÒ׺ 
ÓÑÔÐ Ø Ø Ë Ø

Ø ÓÒ׺ 
ÓÒØ ÜØ Ë Ø¼ Ö ¸ 
Ø ÓÒ׺ ÔÖÓ 
Ø Ë Ø¼ Ö ¸ ÔÖÓ 
Ø×º Ë Ø½ Ö¼¸ ÔÖÓ 
Ø
Ë Ø½ Ö½¸ ÔÖÓ 
Ø×º ×
Ö ÔØ ÓÒ Ë Ø½ Ö¾¸ ÔÖÓ 
Ø×º 
Ø Ú Ë Ø½ Ö¿¸ 
ÓÒØ ÜØ×º Ë Ø¾ Ö¼

ÓÒØ ÜØ×º Ò Ñ Ë Ø¾ Ö½ ÊÇÅ 
Ø ÓÒ× Ä Ì ÇÍÌ Ê ÂÇÁÆ ÔÖÓ 
Ø× ÇÆ ÔÖÓ 
Ø×º 
Ø ÓÒ׺ÔÖÓ
Ä Ì ÇÍÌ Ê ÂÇÁÆ 
ÓÒØ ÜØ× ÇÆ 
ÓÒØ ÜØ×º 
Ø ÓÒ׺
ÓÒØ ÜØ ÏÀ Ê ´ 
Ø ÓÒ׺ µ
Ao invés de duas declaração temos somente uma. Para relacionamentos múltiplos, isso pode
reduzir centenas ou milhares de chamadas ao banco em uma única chamada. Veja por exemplo
a diferença entre as duas chamadas abaixo, depois de criarmos três ações:

Ø ÓÒº Ò ´ Ðеº
ÓÐÐ 
Ø ß ºÔÖÓ 
ØºÒ Ñ ¸ º
ÓÒØ ÜØºÒ Ñ ℄
Ù Ð ÀÓÙ× ¸ ÀÓÑ ℄¸ ÈÐ ÒØ ÌÖ ¸ ÏÓÖ ℄¸ ÏÖ Ø ÓÓ ¸ ÀÓÑ ℄℄
O objetivo da chamada é retornar uma coleção dos nomes dos projetos e contextos de cada
ação existe no banco, em pares. A chamada acima gera os seguintes comandos:

Ø ÓÒ ÄÓ ´¼º¼¼¾ ¿ µ Ë Ä Ì ¶ ÊÇÅ 
Ø ÓÒ×
ÈÖÓ 
Ø ÄÓ ´¼º¼¼¾½ ½µ Ë Ä Ì ¶ ÊÇÅ ÔÖÓ 
Ø× ÏÀ Ê ´ÔÖÓ 
Ø×º ½µ ÄÁÅÁÌ ½
ÓÒØ ÜØ ÄÓ ´¼º¼¼¼ ¿ µ Ë Ä Ì ¶ ÊÇÅ 
ÓÒØ ÜØ× ÏÀ Ê ´
ÓÒØ ÜØ×º ½µ ÄÁÅÁÌ ½
ÈÖÓ 
Ø ÄÓ ´¼º¼¼½¾¾¼µ Ë Ä Ì ¶ ÊÇÅ ÔÖÓ 
Ø× ÏÀ Ê ´ÔÖÓ 
Ø×º ¾µ ÄÁÅÁÌ ½
ÓÒØ ÜØ ÄÓ ´¼º¼¼½½½ µ Ë Ä Ì ¶ ÊÇÅ 
ÓÒØ ÜØ× ÏÀ Ê ´
ÓÒØ ÜØ×º ¾µ ÄÁÅÁÌ ½
ÈÖÓ 
Ø ÄÓ ´¼º¼¼½¾¾ µ Ë Ä Ì ¶ ÊÇÅ ÔÖÓ 
Ø× ÏÀ Ê ´ÔÖÓ 
Ø×º ¿µ ÄÁÅÁÌ ½
ÓÒØ ÜØ ÄÓ ´¼º¼¼½¼ µ Ë Ä Ì ¶ ÊÇÅ 
ÓÒØ ÜØ× ÏÀ Ê ´
ÓÒØ ÜØ×º ½µ ÄÁÅÁÌ ½
Agora, vamos mudar a chamada para:
105
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF

Ø ÓÒº Ò ´ Ðи Ò
ÐÙ ÔÖÓ 
ظ 
ÓÒØ ÜØ℄µº
ÓÐÐ 
Ø ß ºÔÖÓ 
ØºÒ Ñ ¸ º
ÓÒØ
Ù Ð ÀÓÙ× ¸ ÀÓÑ ℄¸ ÈÐ ÒØ ÌÖ ¸ ÏÓÖ ℄¸ ÏÖ Ø ÓÓ ¸ ÀÓÑ ℄℄
Veremos, ao executá-la, que somente uma chamada será feita:

Ø ÓÒ ÄÓ ÁÒ
ÐÙ Ò ××Ó
 Ø ÓÒ× ´¼º¼¼ ½ µ Ë Ä Ì 
Ø ÓÒ׺ Ë Ø¼ Ö¼¸ 
Ø ÓÒ׺ ×
Ö
Ë Ø¼ Ö½¸ 
Ø ÓÒ׺ ÓÒ Ë Ø¼ Ö¾¸ 
Ø ÓÒ׺ 
Ö Ø Ø Ë Ø¼ Ö¿¸ 
Ø ÓÒ׺ 
ÓÑÔÐ Ø Ø Ë Ø

Ø ÓÒ׺ 
ÓÒØ ÜØ Ë Ø¼ Ö ¸ 
Ø ÓÒ׺ ÔÖÓ 
Ø Ë Ø¼ Ö ¸ ÔÖÓ 
Ø×º Ë Ø½ Ö¼¸ ÔÖÓ 
Ø
Ë Ø½ Ö½¸ ÔÖÓ 
Ø×º ×
Ö ÔØ ÓÒ Ë Ø½ Ö¾¸ ÔÖÓ 
Ø×º 
Ø Ú Ë Ø½ Ö¿¸ 
ÓÒØ ÜØ×º Ë Ø¾ Ö¼

ÓÒØ ÜØ×º Ò Ñ Ë Ø¾ Ö½ ÊÇÅ 
Ø ÓÒ× Ä Ì ÇÍÌ Ê ÂÇÁÆ ÔÖÓ 
Ø× ÇÆ ÔÖÓ 
Ø×º 
Ø ÓÒ׺ÔÖÓ
Ä Ì ÇÍÌ Ê ÂÇÁÆ 
ÓÒØ ÜØ× ÇÆ 
ÓÒØ ÜØ×º 
Ø ÓÒ׺
ÓÒØ ÜØ
É fácil ver que essa chamada é bem melhor do que as demais e isso considerando alguns
poucos registros. Em casos de modelos mais complexos, a partir do Rails 1.1 a declaração
include é recursiva. Você poderia ter algo como:
ÓÖ Ö× ÇÖ Ñº Ò Ðи Ò
ÐÙ Ø Ñ× ß ÔÖÓ Ù
ظ ×
ÓÙÒØ ¸ × Ð ×Ô Ö×ÓÒ℄
O código acima buscaria todas as ordens de compra presentes em um banco de dados, carre-
gando automaticamente seus itens e a pessoa que a vendeu. Além disso, para os itens, também
carregaria os objetos descrevendo o produto associado e o desconto dado. As combinações são
infinitas e basta você manter a possibilidade em mente para aplicá-la em suas próprias aplica-
ções.
Vamos agora introduzir nossa modificação final em nosso modelo de dados, as validações:

Ð ×× 
Ø ÓÒ 
Ø Ú Ê 
ÓÖ ×
ØØÖ ÔÖÓØ 
Ø 
Ö Ø Ø¸ 
ÓÑÔÐ Ø Ø
ÓÒ ´Ú ÐÙ µ

Ø Ú Ê 
ÓÖ ÓÒÒ 
Ø ÓÒ ÔØ Ö× ÓÐÙÑÒºÚ ÐÙ ØÓ ÓÓÐ Ò´Ú ÐÙ µ
× Ð º
ÓÑÔÐ Ø Ø Ø Ì Ñ ºÒÓÛ
Ð×
× Ð º
ÓÑÔÐ Ø Ø Ò Ð
Ò
ÛÖ Ø ØØÖ ÙØ ´ ÓÒ ¸ Ú ÐÙ µ
Ò
ÐÓÒ × ØÓ 
ÓÒØ ÜØ
ÐÓÒ × ØÓ ÔÖÓ 
Ø
Ú Ð Ø × ÔÖ × Ò
 Ó ×
Ö ÔØ ÓÒ
Ú Ð Ø × ÔÖ × Ò
 Ó 
ÓÒØ ÜØ
Ú Ð Ø × ÔÖ × Ò
 Ó ÔÖÓ 
Ø
Ò
Agora que temos os nossos relacionamentos, podemos atualizar o nosso controller e as views
geradas para o mesmo. Primeiro, o controller:

Ð ×× 
Ø ÓÒ× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
106
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
 
Ø ÓÒ Ô ×¸  
Ø ÓÒ× Ô Ò Ø 
Ø ÓÒ׸ Ô Ö Ô ¸ ÓÖ Ö ×
Ö ÔØ ÓÒ
Ò
Ø

ÓÒØ ÜØ× ÓÒØ ÜØº Ò ´ Ðи ÓÖ Ö Ò Ñ µº
ÓÐÐ 
Ø ß ºÒ Ñ ¸ º ℄
ÔÖÓ 
Ø× ÈÖÓ 
غ Ò ´ Ðи ÓÖ Ö Ò Ñ µº
ÓÐÐ 
Ø ß ºÒ Ñ ¸ º ℄
Ô Ö Ñ× ℄
 
Ø ÓÒ 
Ø ÓÒº Ò ´Ô Ö Ñ× ℄µ
Ð×
 
Ø ÓÒ 
Ø ÓÒºÒ Û
Ò
Ö ÕÙ ×ØºÔÓר
 
Ø ÓÒº ØØÖ ÙØ × Ô Ö Ñ× 
Ø ÓÒ℄
 
Ø ÓÒº× Ú
Ð × ÒÓØ 
 ℄ Ì 
Ø ÓÒ Û × ×Ù

 ×× ÙÐÐÝ × Ú
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Ò
Ð Ø

Ø ÓÒº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ
Ð × ÒÓØ 
 ℄ Ì 
Ø ÓÒ Û × ×Ù

 ×× ÙÐÐÝ Ð Ø
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
As duas linhas acrescentadas criam arrays de pares com os nomes e identificadores dos
objetos buscados. Precisamos desses arrays para a nossa view de edição, como vemos abaixo:
½ ±  
Ø ÓÒºÒ Û Ö 
ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± 
Ø ÓÒ » ½
± ÖÖÓÖ Ñ ×× × ÓÖ 
Ø ÓÒ ±
± ר ÖØ ÓÖÑ Ø 
Ø ÓÒ Ø ¸  
Ø ÓÒ ±
Ô
Ð Ð ÓÖ 
Ø ÓÒ ×
Ö ÔØ ÓÒ ×
Ö ÔØ ÓÒ »Ð Ð Ö
± Ø ÜØ Ö 
Ø ÓÒ ¸ ×
Ö ÔØ ÓÒ ¸ ÖÓÛ× ±
»Ô
Ô
Ð Ð ÓÖ 
Ø ÓÒ ÓÒ ÓÒ »Ð Ð Ö
± × Ð 
Ø 
Ø ÓÒ ¸ ÓÒ ¸ × ¸ ØÖÙ ℄¸ ÆÓ ¸ Ð× ℄℄ ±
»Ô
Ô
Ð Ð ÓÖ 
Ø ÓÒ 
ÓÒØ ÜØ ÓÒØ ÜØ »Ð Ð Ö
± × Ð 
Ø 
Ø ÓÒ ¸ 
ÓÒØ ÜØ ¸ 
ÓÒØ ܨ׏ ÔÖÓÑÔØ ¹¹ ÓÓ× ¹¹ ±
»Ô
Ô
Ð Ð ÓÖ 
Ø ÓÒ ÔÖÓ 
Ø ÈÖÓ 
Ø »Ð Ð Ö
± × Ð 
Ø 
Ø ÓÒ ¸ ÔÖÓ 
Ø ¸ ÔÖÓ 
Ø×¸ ÔÖÓÑÔØ ¹¹ ÓÓ× ¹¹ ±
107
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
»Ô
Ô
± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò
 Ð ¸ 
Ø ÓÒ Ð ×Ø ±
»Ô
± Ò ÓÖÑ Ø ±
Selecionar os objetos e gerar as estruturas que precisamos no controller é um prática reco-
mendada porque mantemos a nossa view limpa e podemos fazer quaisquer ordenações e filtros
sem nos preocuparmos com o design da aplicação. O parâmetro prompt, passado acima, permite
que um indicador da seleção apareça antes dos valores propriamente ditos.
O formulário resultante fica assim:
Figura 34
Agora voltamos ao pequeno problema que indicamos existir nesse controller anteriormente.
Se você tentar salvar uma ação agora, verá que um erro acontece:
108
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 35
Esse erro é causado por um detalhe. No Rails, a chave params[:action] já é tomada pelo
nome da ação que está sendo executada e como temos um objeto com esse nome, acabamos
com um problema. Entretanto, a solução é simples: basta renomear o nosso objeto. Podemos,
por exemplo, chamá-lo de item.
Primeiro, mudamos o controller:

Ð ×× 
Ø ÓÒ× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
 
Ø ÓÒ Ô ×¸  
Ø ÓÒ× Ô Ò Ø 
Ø ÓÒ׸ Ô Ö Ô ¸ ÓÖ Ö ×
Ö ÔØ ÓÒ
Ò
Ø

ÓÒØ ÜØ× ÓÒØ ÜØº Ò ´ Ðи ÓÖ Ö Ò Ñ µº
ÓÐÐ 
Ø ß ºÒ Ñ ¸ º ℄
ÔÖÓ 
Ø× ÈÖÓ 
غ Ò ´ Ðи ÓÖ Ö Ò Ñ µº
ÓÐÐ 
Ø ß ºÒ Ñ ¸ º ℄
Ô Ö Ñ× ℄
109
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
 Ø Ñ 
Ø ÓÒº Ò ´Ô Ö Ñ× ℄µ
Ð×
 Ø Ñ 
Ø ÓÒºÒ Û
Ò
Ö ÕÙ ×ØºÔÓר
 Ø Ñº ØØÖ ÙØ × Ô Ö Ñ× Ø Ñ℄
 Ø Ñº× Ú
Ð × ÒÓØ 
 ℄ Ì 
Ø ÓÒ Û × ×Ù

 ×× ÙÐÐÝ × Ú
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Ò
Ð Ø

Ø ÓÒº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ
Ð × ÒÓØ 
 ℄ Ì 
Ø ÓÒ Û × ×Ù

 ×× ÙÐÐÝ Ð Ø
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
E depois mudamos a view:
½ ±  Ø ÑºÒ Û Ö 
ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± 
Ø ÓÒ » ½
± ÖÖÓÖ Ñ ×× × ÓÖ Ø Ñ ±
± ר ÖØ ÓÖÑ Ø 
Ø ÓÒ Ø ¸  Ø Ñ ±
Ô
Ð Ð ÓÖ Ø Ñ ×
Ö ÔØ ÓÒ ×
Ö ÔØ ÓÒ »Ð Ð Ö
± Ø ÜØ Ö Ø Ñ ¸ ×
Ö ÔØ ÓÒ ¸ ÖÓÛ× ±
»Ô
Ô
Ð Ð ÓÖ Ø Ñ ÓÒ ÓÒ »Ð Ð Ö
± × Ð 
Ø Ø Ñ ¸ ÓÒ ¸ ÆÓ ¸ Ð× ℄¸ × ¸ ØÖÙ ℄℄ ±
»Ô
Ô
Ð Ð ÓÖ Ø Ñ 
ÓÒØ ÜØ ÓÒØ ÜØ »Ð Ð Ö
± × Ð 
Ø Ø Ñ ¸ 
ÓÒØ ÜØ ¸ 
ÓÒØ ܨ׏ ÔÖÓÑÔØ ¹¹ ÓÓ× ¹¹ ±
»Ô
Ô
Ð Ð ÓÖ Ø Ñ ÔÖÓ 
Ø ÈÖÓ 
Ø »Ð Ð Ö
± × Ð 
Ø Ø Ñ ¸ ÔÖÓ 
Ø ¸ ÔÖÓ 
Ø×¸ ÔÖÓÑÔØ ¹¹ ÓÓ× ¹¹ ±
»Ô
Ô
± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò
 Ð ¸ 
Ø ÓÒ Ð ×Ø ±
»Ô
± Ò ÓÖÑ Ø ±
Esse é um caso raro, mas se você vir algum erro misterioso acontecendo do Rails onde tudo
deveria estar funcionando, verifique se não há um conflito.
Como um detalhe extra, invertemos acima a ordem do Yes e No na seleção da situação ativa
para o correto que seriam uma ação ainda não concluída por padrão. Rodando agora a ação,
110
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
temos o resultado desejado.
Vamos agora modificar o controller mais uma vez em apoio à view de listagem dos dados.
Teríamos o seguinte:

Ð ×× 
Ø ÓÒ× ÓÒØÖÓÐÐ Ö ÔÔÐ 
 Ø ÓÒ ÓÒØÖÓÐÐ Ö
Ò Ü
Ð ×Ø
Ö Ò Ö 
Ø ÓÒ Ð ×Ø
Ò
Ð ×Ø
 
Ø ÓÒ Ô ×¸  
Ø ÓÒ× Ô Ò Ø 
Ø ÓÒ׸ Ò
ÐÙ ÔÖÓ 
ظ 
ÓÒØ ÜØ℄¸
Ô Ö Ô ¸ ÓÖ Ö 
Ø ÓÒ׺ ×
Ö ÔØ ÓÒ
Ò
Ø

ÓÒØ ÜØ× ÓÒØ ÜØº Ò ´ Ðи ÓÖ Ö Ò Ñ µº
ÓÐÐ 
Ø ß ºÒ Ñ ¸ º ℄
ÔÖÓ 
Ø× ÈÖÓ 
غ Ò ´ Ðи ÓÖ Ö Ò Ñ µº
ÓÐÐ 
Ø ß ºÒ Ñ ¸ º ℄
Ô Ö Ñ× ℄
 Ø Ñ 
Ø ÓÒº Ò ´Ô Ö Ñ× ℄µ
Ð×
 Ø Ñ 
Ø ÓÒºÒ Û
Ò
Ö ÕÙ ×ØºÔÓר
 Ø Ñº ØØÖ ÙØ × Ô Ö Ñ× Ø Ñ℄
 Ø Ñº× Ú
Ð × ÒÓØ 
 ℄ Ì 
Ø ÓÒ Û × ×Ù

 ×× ÙÐÐÝ × Ú
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
Ò
Ð Ø

Ø ÓÒº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ
Ð × ÒÓØ 
 ℄ Ì 
Ø ÓÒ Û × ×Ù

 ×× ÙÐÐÝ Ð Ø
Ö Ö 
Ø ØÓ 
Ø ÓÒ Ð ×Ø
Ò
Ò
A inclusão dos relacionamentos irá melhorar a nossa view. Veja que precisamos agora espe-
cificar a condição de ordenação mais claramente, já que temos uma coluna chamada description
em duas tabelas.
Nossa view ficaria assim:
½ 
Ø ÓÒ× » ½
± Ð × ÒÓØ 
 ℄ ±
Ô ×ØÝÐ 
ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð 
 ± Ð × ÒÓØ 
 ℄ ± »Ô
± Ò ±
Ô ± Ð Ò ØÓ Æ Û 
Ø ÓÒ ¸ 
Ø ÓÒ Ø ± »Ô
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø ×
Ö ÔØ ÓÒ »Ø
111
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Ø ÓÑÔÐ Ø »Ø
Ø ÈÖÓ 
Ø »Ø
Ø ÓÒØ ÜØ »Ø
Ø 
Ø ÓÒ× »Ø
»ØÖ
±  
Ø ÓÒ׺ 
 Ó 
Ø ÓÒ ±
ØÖ
Ø ± 
Ø ÓÒº ×
Ö ÔØ ÓÒ ± »Ø
Ø ± Ý × ÓÖ ÒÓ ´ 
Ø ÓÒº ÓÒ µ ± »Ø
Ø ± 
Ø ÓÒºÔÖÓ 
ØºÒ Ñ ± »Ø
Ø ± 
Ø ÓÒº
ÓÒØ ÜØºÒ Ñ ± »Ø
Ø
± Ð Ò ØÓ Ø ¸ 
Ø ÓÒ Ø ¸ 
Ø ÓÒ ± ÓÖ
± Ð Ò ØÓ Ð Ø ¸ ß 
Ø ÓÒ Ð Ø ¸ 
Ø ÓÒ ¸ 
ÓÒ ÖÑ Ö ÝÓÙ ×ÙÖ
ȯ
»ØÖ
± Ò ±
»Ø Ð
Ô ± Ô Ò Ø ÓÒ Ð Ò ×´ 
Ø ÓÒ Ô ×µ ± »Ô
Dando o seguinte resultado:
112
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 36
Se quisermos, podemos também acrescentar um campo informando quando a ação foi com-
pletada, formatando a data em que a mesma foi completada da maneira necessária à nossa
aplicação, ou exibindo um marcador caso contrário. Nossa view poderia ficar como algo assim:
½ 
Ø ÓÒ× » ½
± Ð × ÒÓØ 
 ℄ ±
Ô ×ØÝÐ 
ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð 
 ± Ð × ÒÓØ 
 ℄ ± »Ô
± Ò ±
Ô ± Ð Ò ØÓ Æ Û 
Ø ÓÒ ¸ 
Ø ÓÒ Ø ± »Ô
Ø Ð ÓÖ Ö ½ 
 ÐÐÔ Ò 
 ÐÐ×Ô 
 Ò ½
ØÖ
Ø ×
Ö ÔØ ÓÒ »Ø
Ø ÓÑÔÐ Ø »Ø
Ø Ï Ò »Ø
Ø ÈÖÓ 
Ø »Ø
Ø ÓÒØ ÜØ »Ø
Ø 
Ø ÓÒ× »Ø
»ØÖ
±  
Ø ÓÒ׺ 
 Ó 
Ø ÓÒ ±
ØÖ
Ø ± 
Ø ÓÒº ×
Ö ÔØ ÓÒ ± »Ø
Ø ± Ý × ÓÖ ÒÓ ´ 
Ø ÓÒº ÓÒ µ ± »Ø
Ø ± ´ 
Ø ÓÒº ÓÒ µ 
Ø ÓÒº
ÓÑÔÐ Ø Øº×ØÖ Ø Ñ ´ ±Ñ»± »±Ý µ ¹ ± »Ø
Ø ± 
Ø ÓÒºÔÖÓ 
ØºÒ Ñ ± »Ø
Ø ± 
Ø ÓÒº
ÓÒØ ÜØºÒ Ñ ± »Ø
Ø
± Ð Ò ØÓ Ø ¸ 
Ø ÓÒ Ø ¸ 
Ø ÓÒ ± ÓÖ
± Ð Ò ØÓ Ð Ø ¸ ß 
Ø ÓÒ Ð Ø ¸ 
Ø ÓÒ ¸ 
ÓÒ ÖÑ Ö ÝÓÙ ×ÙÖ
ȯ
»ØÖ
± Ò ±
»Ø Ð
Ô ± Ô Ò Ø ÓÒ Ð Ò ×´ 
Ø ÓÒ Ô ×µ ± »Ô
Com o seguinte resultado:
113
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Figura 37
114
Capítulo 12
Has many, has one, has many through
Além do relacionamento belongs_to, o Rails também possui um outro relacionamento cha-
mado has_many, has one, e has many, through. Essa lição visa explicar cada um deles.
12.1 Has many
Como o próprio nome indica, esse relacionamento diz que um modelo possui muitos de outros
modelos. Em nossa aplicação, nos temos duas instâncias imediatas disso: um contexto possui
muitas ações e um projeto possui muitas ações.
Modificando inicialmente o modelo de contextos, teríamos:

Ð ×× ÓÒØ ÜØ 
Ø Ú Ê 
ÓÖ ×
Ú Ð Ø × ÔÖ × Ò
 Ó Ò Ñ
Ú Ð Ø × ÙÒ ÕÙ Ò ×× Ó Ò Ñ ¸ Ñ ×× ÑÙר ÙÒ ÕÙ
× Ñ ÒÝ 
Ø ÓÒ×
Ò
Isso é suficiente para estabelecer uma série de métodos adicionais que permitem que você
manipule as ações relacionadas a um contexto. Usando o console, podemos ver algumas delas:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ»
ÓÒ×ÓÐ
ÄÓ Ò Ú ÐÓÔÑ ÒØ ÒÚ ÖÓÒÑ ÒØº

ÓÒØ ÜØ ÓÒØ ÜØº Ò ´½µ
ÓÒØ ÜØ ¼Ü ¿ ½  ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½

ÓÒØ ÜØº 
Ø ÓÒ׺
ÓÙÒØ
½

ÓÒØ ÜØº 
Ø ÓÒ×

Ø ÓÒ ¼Ü ¿ ¾ 
  ØØÖ ÙØ × ß 
ÓÒØ ÜØ ½ ¸ 
ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ 
Ø ¿
ÓÒ ¼ ¸ ¸ ×
Ö ÔØ ÓÒ Ë Ø ÓÛÒ Ò ÛÖ Ø ¸ Ú ÖÝ Ý¸ Ø Ð ×Ø ØÛÓ ÓÙÖ×

Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¿½ ½ ℄
Se criarmos mais uma ação associada a esse contexto, teríamos algo assim:

Ø ÓÒ 
Ø ÓÒº
Ö Ø ´ ×
Ö ÔØ ÓÒ ÙÝ Ö ÑÑ Ö ØÓ ÐÔ Ñ Û Ø ÑÝ Ò Ð × º ¸ 
ÓÒØ
½¸ ÔÖÓ 
Ø ¿µ

Ø ÓÒ ¼Ü Ò Û Ö 
ÓÖ Ð× ¸  ÖÖÓÖ× 
Ø Ú Ê 
ÓÖ ÖÖÓÖ× ¼Ü
115
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
 × 
Ø ÓÒ ¼Ü ººº ¸  ÖÖÓÖ× ß ¸  ØØÖ ÙØ × ß 
ÓÒØ ÜØ ½¸ 
ÓÑÔÐ Ø Ø Ò
ÔÖÓ 
Ø ¿¸ ÓÒ Ò Ð¸ ½½¸ ×
Ö ÔØ ÓÒ ÙÝ Ö ÑÑ Ö ØÓ ÐÔ Ñ Û Ø ÑÝ Ò Ð

Ö Ø Ø Ì Ù Ë Ô ¾½ ½ ¾ ¼ ÊÌ ¾¼¼

ÓÒØ ÜØº 
Ø ÓÒ×

Ø ÓÒ ¼Ü ¿ ¾ 
  ØØÖ ÙØ × ß 
ÓÒØ ÜØ ½ ¸ 
ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ 
Ø ¿
ÓÒ ¼ ¸ ¸ ×
Ö ÔØ ÓÒ Ë Ø ÓÛÒ Ò ÛÖ Ø ¸ Ú ÖÝ Ý¸ Ø Ð ×Ø ØÛÓ ÓÙÖ×

Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¿½ ½ ℄

ÓÒØ ÜØº 
Ø ÓÒ×ºÖ ÐÓ

Ø ÓÒ ¼Ü 

  ØØÖ ÙØ × ß 
ÓÒØ ÜØ ½ ¸ 
ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ 
Ø ¿
ÓÒ ¼ ¸ ¸ ×
Ö ÔØ ÓÒ Ë Ø ÓÛÒ Ò ÛÖ Ø ¸ Ú ÖÝ Ý¸ Ø Ð ×Ø ØÛÓ ÓÙÖ×

Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¿½ ½ ¸ 
Ø ÓÒ ¼Ü ¼  ØØÖ ÙØ × ß 
ÓÒØ ÜØ ½ ¸

ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ 
Ø ¿ ¸ ÓÒ Ò Ð¸ ½½ ¸ ×
Ö ÔØ ÓÒ ÙÝ Ö ÑÑ
ÐÔ Ñ Û Ø ÑÝ Ò Ð × º ¸ 
Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¾ ¼ ℄

ÓÒØ ÜØº 
Ø ÓÒ׺
ÓÙÒØ
¾

ÓÒØ ÜØº 
Ø ÓÒ׺ ÑÔØÝ
Ð×
Note que, como usando um objeto já carregado, a coleção de ações não foi recarregada
depois que uma nova ação foi adicionada. Isso acontece porque o Rails faz um cache de coleções
e a ação foi adicionada através de seu próprio constructor e não usando os métodos da coleção.
O método reload pode ser usado para recarregar a coleção caso você precise.
Um outro exemplo seria:

ÓÒØ ÜØº 
Ø ÓÒ× 
Ø ÓÒº
Ö Ø ´ ×
Ö ÔØ ÓÒ ÍÔ Ö ÑÝ ÛÓÖ ÔÖÓ
 ××ÓÖº ¸ ÔÖÓ 
Ø

Ø ÓÒ ¼Ü 

  ØØÖ ÙØ × ß 
ÓÒØ ÜØ ½ ¸ 
ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ 
Ø ¿
ÓÒ ¼ ¸ ¸ ×
Ö ÔØ ÓÒ Ë Ø ÓÛÒ Ò ÛÖ Ø ¸ Ú ÖÝ Ý¸ Ø Ð ×Ø ØÛÓ ÓÙÖ×

Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¿½ ½ ¸ 
Ø ÓÒ ¼Ü ¼  ØØÖ ÙØ × ß 
ÓÒØ ÜØ ½ ¸

ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ 
Ø ¿ ¸ ÓÒ Ò Ð¸ ½½ ¸ ×
Ö ÔØ ÓÒ ÙÝ Ö ÑÑ
ÐÔ Ñ Û Ø ÑÝ Ò Ð × º ¸ 
Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¾ ¼ ¸ 
Ø ÓÒ ¼Ü ¿½ ¼
Ò Û Ö 
ÓÖ Ð× ¸  ÖÖÓÖ× 
Ø Ú Ê 
ÓÖ ÖÖÓÖ× ¼Ü ½¿ ¼  × 
Ø ÓÒ ¼Ü ¿½ ¼ ººº ¸
 ÖÖÓÖ× ß ¸  ØØÖ ÙØ × ß 
ÓÒØ ÜØ ½¸ 
ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ 
Ø ¿¸ ÓÒ Ò Ð¸
½¾¸ ×
Ö ÔØ ÓÒ ÍÔ Ö ÑÝ ÛÓÖ ÔÖÓ
 ××ÓÖº ¸ 
Ö Ø Ø Ì Ù Ë Ô ¾½ ½ ¾½ ÊÌ

ÓÒØ ÜØº 
Ø ÓÒ×º× Þ
¿
Nesse caso, você pode ver que duas coisas aconteceram: primeiro, não foi necessário in-
formar o contexto, que é pego automaticamente no objeto; segundo: a coleção cresceu auto-
maticamente, já que estamos manipulando os dados diretamente na mesma. Ao invés de usar
os métodos acima para criar a ação, você pode usar diretamente os métodos build e create na
coleção para adicionar novos dados. O primeiro funciona para objetos já existentes na coleção
e o segundo para adicionar um novo objeto. Uma coleção também possui um método find para
encontrar objetos dentro da mesma, de acordo com as mesmas regras do método find usado para
classes de dados. Por fim, por razões de eficiência, toda coleção declara um método do objeto
pai para atribuição rápida de valores. No caso do objeto acima, o método é chamada action_ids
e pode ser usado para trocar completamente os dados de uma coleção.
Por exemplo:

ÓÒØ ÜØº 
Ø ÓÒ × ½¸ ¾¸ ℄
116
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Isso removeria qualquer ação associada àquele contexto, substituindo-as pelas ações identi-
ficadas pelos ids acima.
A coleção toda pode ser substituída com objetos também, como mostrado abaixo:

ÓÒØ ÜØº 
Ø ÓÒ× 
Ø ÓÒº Ò ´ Ðи 
ÓÒ Ø ÓÒ× ÔÖÓ 
Ø ¸ ℄µ
O contexto acima teria todas as suas ações substituídas pelas ações associadas ao projeto
cujo id é 5.
Investigando a documentação você poderá encontrar mais detalhes sobre como cada método
funciona. Um exemplo disso é a destruição automática de registros quando um registro pai for
excluído. Isso pode fazer um objeto ter a funcionalidade equivalente de uma declaração cascade
em um banco de dados.
Uma coisa que deve ser notada é que muitos desse métodos causam o salvamento imediato
dos dados (se o objeto pai já está salvo). Com a prática, você será capaz de identificar quais são
esses métodos e agir apropriadamente caso queria outra ação, embora o comportamento padrão
seja o desejado na maior parte dos casos.
Não vamos utilizar esses métodos em nossa aplicação no momento porque veremos uma
aplicação similar mais à frente com outro tipo de relacionamento parecido.
12.2 Has one
Dois outros relacionamentos existentes no Rails são has_and_belongs_to_many e has_one.
O relacionamento has_one geralmente expressa o oposto do relacionamento belongs_to. Por
exemplo, digamos que temos duas tabelas: uma contendo cartões de crédito e outra contendo o
titulares de cartões. Na tabela de cartão de crédito teríamos uma chave estrangeira apontando
para o seu titular. Teríamos então as seguintes classes:

Ð ×× Ö Ø Ö 
Ø Ú Ê 
ÓÖ ×
ÐÓÒ × ØÓ 

ÓÙÒØ ÓÐ Ö
Ò

Ð ×× 

ÓÙÒØÀÓÐ Ö 
Ø Ú Ê 
ÓÖ ×
× ÓÒ 
Ö Ø 
 Ö
Ò
A diferença é que a chave estrangeira existe somente na tabela relacionada à classe Credit-
Card, sendo automaticamente deduzida no relacionamento inverso.
Esse exemplo não é muito bom já que, em tese, uma pessoa poderia ter vários cartões de
crédito. Mas a idéia é essa. Na prática, esse tipo de relacionamento é mais raro e geralmente
tende a se transformar em relacionamentos do tipo has_many ou has_many_and_belongs_to.
O relacionamento has_many_and_belongs_to, por sua vez, representa a intermediação entre
duas tabelas.
Por exemplo, a relação entre desenvolvedores e projetos em uma empresa. Um desenvol-
vedor pode estar locado em múltiplos projetos e um projeto pode ter múltiplos desenvolvedores.
Veremos mais detalhes desse relacionamento adiante quando fizermos mais modificações em
nossa aplicação para suportar outras características.
117
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
12.3 Has many, trough
Um tipo interessante de relacionamento, introduzido no Rails 1.1, é aquele relacionamento
em que uma tabela intermediária é usada para colapsar outra. Digamos, por exemplo, que você
tenha modelos representando empresas, clientes e notas ficais e você queira descobrir todas as
notas fiscais emitidas por um empresa qualquer. É aqui que esse tipo de relacionamento entra
em ação, permitindo que o código seja simplificado. Vamos experimentar um pouco, usando o
console.
Digamos que você queria, em nossa aplicação, saber todos os contextos associados a um
projeto. A maneira simples seria fazer isso:
ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ×
Ö ÔØ»
ÓÒ×ÓÐ
ÄÓ Ò Ú ÐÓÔÑ ÒØ ÒÚ ÖÓÒÑ ÒØº
ÔÖÓ 
Ø ÈÖÓ 
غ Ò ´¿µ
ÈÖÓ 
Ø ¼Ü ¼ ¿ 
  ØØÖ ÙØ × ß Ò Ñ ÏÖ Ø ÓÓ ¸ ¿ ¸ ×
Ö ÔØ ÓÒ ¸

Ø Ú ½
ÔÖÓ 
غ 
Ø ÓÒ׺
ÓÐÐ 
Ø ß º
ÓÒØ ÜØºÒ Ñ
ÀÓÑ ¸ ÀÓÑ ¸ ÀÓÑ ℄
Como você pode ver, o contexto é o mesmo para todas as ações associadas àquele projeto e
queremos os contextos sem repetição. Uma solução simples seria:

ÓÒØ ÜØ× ÔÖÓ 
غ 
Ø ÓÒ׺
ÓÐÐ 
Ø ß º
ÓÒØ ÜØºÒ Ñ
ÀÓÑ ¸ ÀÓÑ ¸ ÀÓÑ ℄

ÓÒØ ÜØ×ºÙÒ Õ
ÀÓÑ ℄
O problema é que, além de usar mais código, essa solução é muito ineficiente por causa
das comparações que precisam ser realizadas pelo método uniq. Podemos resolver o problema
usando então a seguinte estratégia:

Ð ×× ÈÖÓ 
Ø 
Ø Ú Ê 
ÓÖ ×
Ú Ð Ø × ÔÖ × Ò
 Ó Ò Ñ
Ú Ð Ø × ÙÒ ÕÙ Ò ×× Ó Ò Ñ
× Ñ ÒÝ 
Ø ÓÒ×
× Ñ ÒÝ 
ÓÒØ ܨ׏ Ø ÖÓÙ 
Ø ÓÒ׸ × Ð 
Ø ×Ø Ò
Ø 
ÓÒØ ÜØ×º¶
Ò
Usando esse método tempos:
ÔÖÓ 
غ
ÓÒØ ÜØ×º
ÓÐÐ 
Ø ß 
 
ºÒ Ñ
ÀÓÑ ℄
Como você pode ver, muito mais fácil e interessante e, em quase todos os casos, mais efici-
ente.
No relacionamento acima, temos os contextos de um projecto obtidos através (through) de
suas ações. Se não for necessário preocupar com cópias (como no exemplo das notas fiscais)
poderemos inclusive descartar o parâmetro select que é um fragmento de SQL usado no lugar
do gerado automaticamente pelo Rails.
118
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF
Associações through são muito poderosas e podem ser utilizadas em várias situações para
agilizar o código e melhorar a legibilidade da aplicação.
Com isso, chegamos ao fim do nosso curso do básico de Ruby on Rails. Espero que venha a
ser útil para vocês.
119

Mais conteúdo relacionado

PDF
Vim
PDF
Squid
PDF
Quanta
PDF
Shell script
PDF
Apostila cdtc dotproject
PDF
Uml
Vim
Squid
Quanta
Shell script
Apostila cdtc dotproject
Uml

Mais procurados (20)

PDF
Wx python
PDF
Squid guard
PDF
X dialog
PDF
Tunelamento
PDF
Qemu
PDF
Samba
PDF
Screen
PDF
Manipulando pacotes
PDF
Selinux
PDF
Xdmcp
PDF
Drivers de Dispositivos Linux
PDF
Javascript
PDF
Servidor de emails_seguro
PDF
Tcl tk
PDF
Horde
PDF
Python gtk
PDF
Jspservlets
PDF
Jdbc
PDF
Java Basico
PDF
Java applet
Wx python
Squid guard
X dialog
Tunelamento
Qemu
Samba
Screen
Manipulando pacotes
Selinux
Xdmcp
Drivers de Dispositivos Linux
Javascript
Servidor de emails_seguro
Tcl tk
Horde
Python gtk
Jspservlets
Jdbc
Java Basico
Java applet
Anúncio

Semelhante a Ruby on rails (20)

PDF
Linguagem ruby
PDF
Drupal
PDF
Instalacao xoops
PDF
Nvu
PDF
J2me
PDF
Fw builder
PDF
Plone
PDF
Pascal
PDF
Java awt
PDF
Ferm
PDF
Inkscape
PDF
Programacao php moodle
PDF
Planejamento em desenvolvimento_de_sistemas
PDF
Monitoramento
PDF
Http
PDF
Mrtg
PDF
Ps
PDF
Historia da informatica
PDF
Ftp
PDF
Java swing
Linguagem ruby
Drupal
Instalacao xoops
Nvu
J2me
Fw builder
Plone
Pascal
Java awt
Ferm
Inkscape
Programacao php moodle
Planejamento em desenvolvimento_de_sistemas
Monitoramento
Http
Mrtg
Ps
Historia da informatica
Ftp
Java swing
Anúncio

Mais de Tiago (20)

PDF
6572501 ldp-apostila-de-turbo-pascal
PDF
Guia rapido de_pascal
PDF
Python bge
PDF
Curso python
PDF
Curso python
PDF
Aula 01 python
PDF
Threading in c_sharp
PDF
Retirar acentos de_determinado_texto_em_c_sharp
PDF
Remover caracteres especiais_texto_em_c_sharp
PDF
Obter ip da_internet_em_c_sharp
PDF
Metodo using no_c_sharp
PDF
Introdução ao c# para iniciantes
PDF
Interfaces windows em c sharp
PDF
Filestream sistema arquivos
PDF
Curso linux professor rafael
PDF
Curso de shell
PDF
Controle lpt em_c_sharp
PDF
Classes csharp
PDF
C# o basico
PDF
C# classes
6572501 ldp-apostila-de-turbo-pascal
Guia rapido de_pascal
Python bge
Curso python
Curso python
Aula 01 python
Threading in c_sharp
Retirar acentos de_determinado_texto_em_c_sharp
Remover caracteres especiais_texto_em_c_sharp
Obter ip da_internet_em_c_sharp
Metodo using no_c_sharp
Introdução ao c# para iniciantes
Interfaces windows em c sharp
Filestream sistema arquivos
Curso linux professor rafael
Curso de shell
Controle lpt em_c_sharp
Classes csharp
C# o basico
C# classes

Último (20)

PDF
Ebook - Matemática_Ensino_Médio_Saeb_V1.pdf
PPTX
ACIDOS NUCLEICOS - REPLICAÇÃO DO DNA - E.M.
PPT
HISTOLOGIA VEGETAL - tecidos vegetais.ppt
PPTX
INDÚSTRIA_ Histórico da industrialização.pptx
PPT
sistema reprodutor para turmas do oitavo ano
PPTX
HISTÓRIA DO BRASIL - anos de Democracia.pptx
PPTX
Ocupação e transformação dos territórios.pptx
PDF
COMO OS CONTOS DE FADAS REFLETEM ARQUÉTIPOS_MEDOS E DESEJOS DO INCONSCIENTE H...
PPTX
Slides Lição 7, CPAD, Uma Igreja Que Não Teme A Perseguição, 3Tr25.pptx
PPTX
Revolução Industrial - Aula Expositiva - 3U4.pptx
PPTX
QuestõesENEMVESTIBULARPARAESTUDOSEAPRENDIZADO.pptx
PDF
Combate a Incêndio - Estratégias e Táticas de Combate a Incêndio por Francis...
PPTX
Biologia celular: citologia, é o estudo da célula, a unidade básica da vida.
PDF
Ementa 2 semestre PEI Orientação de estudo
PDF
A relação entre funções executivas e desempenho acadêmico em crianças com Tra...
PPTX
GUERRAFRIA.pptdddddddddddddddddddddddddx
PPTX
TREINAMENTO DE INSPETOR DE ANDAIMES.pptx
PDF
manual-orientacao-asb_5a8d6d8d87160aa636f63a5d0.pdf
PPTX
Aula 13 - Tópico Frasal - Argumentação.pptx
PPTX
NR11 - Treinamento Direcao Defensiva - 2023.pptx
Ebook - Matemática_Ensino_Médio_Saeb_V1.pdf
ACIDOS NUCLEICOS - REPLICAÇÃO DO DNA - E.M.
HISTOLOGIA VEGETAL - tecidos vegetais.ppt
INDÚSTRIA_ Histórico da industrialização.pptx
sistema reprodutor para turmas do oitavo ano
HISTÓRIA DO BRASIL - anos de Democracia.pptx
Ocupação e transformação dos territórios.pptx
COMO OS CONTOS DE FADAS REFLETEM ARQUÉTIPOS_MEDOS E DESEJOS DO INCONSCIENTE H...
Slides Lição 7, CPAD, Uma Igreja Que Não Teme A Perseguição, 3Tr25.pptx
Revolução Industrial - Aula Expositiva - 3U4.pptx
QuestõesENEMVESTIBULARPARAESTUDOSEAPRENDIZADO.pptx
Combate a Incêndio - Estratégias e Táticas de Combate a Incêndio por Francis...
Biologia celular: citologia, é o estudo da célula, a unidade básica da vida.
Ementa 2 semestre PEI Orientação de estudo
A relação entre funções executivas e desempenho acadêmico em crianças com Tra...
GUERRAFRIA.pptdddddddddddddddddddddddddx
TREINAMENTO DE INSPETOR DE ANDAIMES.pptx
manual-orientacao-asb_5a8d6d8d87160aa636f63a5d0.pdf
Aula 13 - Tópico Frasal - Argumentação.pptx
NR11 - Treinamento Direcao Defensiva - 2023.pptx

Ruby on rails

  • 1. Ruby On Rails 9 de Julho de 2008
  • 2. Conteúdo I Sobre essa apostila 3 II Informações Básicas 5 III GNU Free Documentation License 10 IV Ruby on Rails 19 1 O que é o curso Ruby on Rails 20 2 Plano de ensino 21 2.1 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.2 Público Alvo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.3 Pré-requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.4 Descrição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.5 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.6 Cronograma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.7 Programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.8 Avaliação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.9 Bibliografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3 Iniciando o Ruby on Rails 24 3.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.2 Instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.3 Configurando Banco de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4 Gerando Migrações e Modelos de Dados 30 4.1 Gerando Migrações e Modelos de dados I . . . . . . . . . . . . . . . . . . . . . . . . 30 5 MVC e CONTROLLER 39 5.1 MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 5.2 O primeiro controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 6 Layouts e Roteamento 43 6.1 Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 6.2 Roteamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 1
  • 3. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF 7 Scaffolding e Validações 48 7.1 Scaffolding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 7.2 Validações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 8 Segundo Controller 56 8.1 Início . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 9 Extendendo um modelo de dados e Helpers 69 9.1 Extendendo um modelo de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 9.2 Usando Helpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 10 Relacionamentos 75 10.1 Início . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 11 Belongs to 81 11.1 Belongs to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 12 Has many, has one, has many through 91 12.1 Has many . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 12.2 Has one . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 12.3 Has many, trough . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 2
  • 4. Parte I Sobre essa apostila 3
  • 5. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Conteúdo O conteúdo dessa apostila é fruto da compilação de diversos materiais livres publicados na in- ternet, disponíveis em diversos sites ou originalmente produzido no CDTC em http://www.cdtc.org.br. O formato original deste material bem como sua atualização está disponível dentro da licença GNU Free Documentation License, cujo teor integral encontra-se aqui reproduzido na seção de mesmo nome, tendo inclusive uma versão traduzida (não oficial). A revisão e alteração vem sendo realizada pelo CDTC (suporte@cdtc.org.br), desde outubro de 2006. Criticas e sugestões construtivas são bem-vindas a qualquer tempo. Autores A autoria deste conteúdo, atividades e avaliações é de responsabilidade de Diego de Aquino Soares (diego@cdtc.org.br). O texto original faz parte do projeto Centro de Difusão de Tecnolgia e Conhecimento, que vem sendo realizado pelo ITI em conjunto com outros parceiros institucionais, atuando em conjunto com as universidades federais brasileiras que tem produzido e utilizado Software Livre, apoiando inclusive a comunidade Free Software junto a outras entidades no país. Informações adicionais podem ser obtidas atréves do email ouvidoria@cdtc.org.br, ou da home page da entidade, através da URL http://www.cdtc.org.br. Garantias O material contido nesta apostila é isento de garantias e o seu uso é de inteira responsabi- lidade do usuário/leitor. Os autores, bem como o ITI e seus parceiros, não se responsabilizam direta ou indiretamente por qualquer prejuízo oriundo da utilização do material aqui contido. Licença Copyright ©2006,Diego de Aquino Soares (diego@cdtc.org.br). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Chapter being SOBRE ESSA APOS- TILA. A copy of the license is included in the section entitled GNU Free Documentation License. 4
  • 7. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Sobre o CDTC Objetivo Geral O Projeto CDTC visa a promoção e o desenvolvimento de ações que incentivem a dissemina- ção de soluções que utilizem padrões abertos e não proprietários de tecnologia, em proveito do desenvolvimento social, cultural, político, tecnológico e econômico da sociedade brasileira. Objetivo Específico Auxiliar o Governo Federal na implantação do plano nacional de software não-proprietário e de código fonte aberto, identificando e mobilizando grupos de formadores de opinião dentre os servidores públicos e agentes políticos da União Federal, estimulando e incentivando o mercado nacional a adotar novos modelos de negócio da tecnologia da informação e de novos negócios de comunicação com base em software não-proprietário e de código fonte aberto, oferecendo treinamento específico para técnicos, profissionais de suporte e funcionários públicos usuários, criando grupos de funcionários públicos que irão treinar outros funcionários públicos e atuar como incentivadores e defensores de produtos de software não proprietários e código fonte aberto, ofe- recendo conteúdo técnico on-line para serviços de suporte, ferramentas para desenvolvimento de produtos de software não proprietários e de seu código fonte livre, articulando redes de terceiros (dentro e fora do governo) fornecedoras de educação, pesquisa, desenvolvimento e teste de pro- dutos de software livre. Guia do aluno Neste guia, você terá reunidas uma série de informações importantes para que você comece seu curso. São elas: • Licenças para cópia de material disponível • Os 10 mandamentos do aluno de Educação a Distância • Como participar dos fóruns e da wikipédia • Primeiros passos É muito importante que você entre em contato com TODAS estas informações, seguindo o roteiro acima. Licença Copyright ©2006, Diego de Aquino Soares (diego@cdtc.org.br). 6
  • 8. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF É dada permissão para copiar, distribuir e/ou modificar este documento sob os termos da Licença de Documentação Livre GNU, Versão 1.1 ou qualquer versão posterior publicada pela Free Software Foundation; com o Capítulo Invariante SOBRE ESSA APOSTILA. Uma cópia da licença está inclusa na seção entitulada "Licença de Docu- mentação Livre GNU". Os 10 mandamentos do aluno de educação online • 1. Acesso a Internet: ter endereço eletrônico, um provedor e um equipamento adequado é pré-requisito para a participação nos cursos a distância. • 2. Habilidade e disposição para operar programas: ter conhecimentos básicos de Informá- tica é necessário para poder executar as tarefas. • 3. Vontade para aprender colaborativamente: interagir, ser participativo no ensino a distân- cia conta muitos pontos, pois irá colaborar para o processo ensino-aprendizagem pessoal, dos colegas e dos professores. • 4. Comportamentos compatíveis com a etiqueta: mostrar-se interessado em conhecer seus colegas de turma respeitando-os e fazendo ser respeitado pelo mesmo. • 5. Organização pessoal: planejar e organizar tudo é fundamental para facilitar a sua revisão e a sua recuperação de materiais. • 6. Vontade para realizar as atividades no tempo correto: anotar todas as suas obrigações e realizá-las em tempo real. • 7. Curiosidade e abertura para inovações: aceitar novas idéias e inovar sempre. • 8. Flexibilidade e adaptação: requisitos necessário a mudança tecnológica, aprendizagens e descobertas. • 9. Objetividade em sua comunicação: comunicar-se de forma clara, breve e transparente é ponto-chave na comunicação pela Internet. • 10. Responsabilidade: ser responsável por seu próprio aprendizado. O ambiente virtual não controla a sua dedicação, mas reflete os resultados do seu esforço e da sua colaboração. Como participar dos fóruns e Wikipédia Você tem um problema e precisa de ajuda? Podemos te ajudar de 2 formas: A primeira é o uso dos fóruns de notícias e de dúvidas gerais que se distinguem pelo uso: O fórum de notícias tem por objetivo disponibilizar um meio de acesso rápido a informações que sejam pertinentes ao curso (avisos, notícias). As mensagens postadas nele são enviadas a 7
  • 9. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF todos participantes. Assim, se o monitor ou algum outro participante tiver uma informação que interesse ao grupo, favor postá-la aqui. Porém, se o que você deseja é resolver alguma dúvida ou discutir algum tópico específico do curso, é recomendado que você faça uso do Fórum de dúvidas gerais que lhe dá recursos mais efetivos para esta prática. . O fórum de dúvidas gerais tem por objetivo disponibilizar um meio fácil, rápido e interativo para solucionar suas dúvidas e trocar experiências. As mensagens postadas nele são enviadas a todos participantes do curso. Assim, fica muito mais fácil obter respostas, já que todos podem ajudar. Se você receber uma mensagem com algum tópico que saiba responder, não se preocupe com a formalização ou a gramática. Responda! E não se esqueça de que antes de abrir um novo tópico é recomendável ver se a sua pergunta já foi feita por outro participante. A segunda forma se dá pelas Wikis: Uma wiki é uma página web que pode ser editada colaborativamente, ou seja, qualquer par- ticipante pode inserir, editar, apagar textos. As versões antigas vão sendo arquivadas e podem ser recuperadas a qualquer momento que um dos participantes o desejar. Assim, ela oferece um ótimo suporte a processos de aprendizagem colaborativa. A maior wiki na web é o site "Wikipé- dia", uma experiência grandiosa de construção de uma enciclopédia de forma colaborativa, por pessoas de todas as partes do mundo. Acesse-a em português pelos links: • Página principal da Wiki - http://pt.wikipedia.org/wiki/ Agradecemos antecipadamente a sua colaboração com a aprendizagem do grupo! Primeiros Passos Para uma melhor aprendizagem é recomendável que você siga os seguintes passos: • Ler o Plano de Ensino e entender a que seu curso se dispõe a ensinar; • Ler a Ambientação do Moodle para aprender a navegar neste ambiente e se utilizar das ferramentas básicas do mesmo; • Entrar nas lições seguindo a seqüência descrita no Plano de Ensino; • Qualquer dúvida, reporte ao Fórum de Dúvidas Gerais. Perfil do Tutor Segue-se uma descrição do tutor ideal, baseada no feedback de alunos e de tutores. O tutor ideal é um modelo de excelência: é consistente, justo e profissional nos respectivos valores e atitudes, incentiva mas é honesto, imparcial, amável, positivo, respeitador, aceita as idéias dos estudantes, é paciente, pessoal, tolerante, apreciativo, compreensivo e pronto a ajudar. 8
  • 10. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF A classificação por um tutor desta natureza proporciona o melhor feedback possível, é crucial, e, para a maior parte dos alunos, constitui o ponto central do processo de aprendizagem.’ Este tutor ou instrutor: • fornece explicações claras acerca do que ele espera, e do estilo de classificação que irá utilizar; • gosta que lhe façam perguntas adicionais; • identifica as nossas falhas, mas corrige-as amavelmente’, diz um estudante, ’e explica por- que motivo a classificação foi ou não foi atribuída’; • tece comentários completos e construtivos, mas de forma agradável (em contraste com um reparo de um estudante: ’os comentários deixam-nos com uma sensação de crítica, de ameaça e de nervosismo’) • dá uma ajuda complementar para encorajar um estudante em dificuldade; • esclarece pontos que não foram entendidos, ou corretamente aprendidos anteriormente; • ajuda o estudante a alcançar os seus objetivos; • é flexível quando necessário; • mostra um interesse genuíno em motivar os alunos (mesmo os principiantes e, por isso, talvez numa fase menos interessante para o tutor); • escreve todas as correções de forma legível e com um nível de pormenorização adequado; • acima de tudo, devolve os trabalhos rapidamente; 9
  • 11. Parte III GNU Free Documentation License 10
  • 12. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF (Traduzido pelo João S. O. Bueno através do CIPSGA em 2001) Esta é uma tradução não oficial da Licençaa de Documentação Livre GNU em Português Brasileiro. Ela não é publicada pela Free Software Foundation, e não se aplica legalmente a dis- tribuição de textos que usem a GFDL - apenas o texto original em Inglês da GNU FDL faz isso. Entretanto, nós esperamos que esta tradução ajude falantes de português a entenderem melhor a GFDL. This is an unofficial translation of the GNU General Documentation License into Brazilian Por- tuguese. It was not published by the Free Software Foundation, and does not legally state the distribution terms for software that uses the GFDL–only the original English text of the GFDL does that. However, we hope that this translation will help Portuguese speakers understand the GFDL better. Licença de Documentação Livre GNU Versão 1.1, Março de 2000 Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA É permitido a qualquer um copiar e distribuir cópias exatas deste documento de licença, mas não é permitido alterá-lo. INTRODUÇÃO O propósito desta Licença é deixar um manual, livro-texto ou outro documento escrito "livre"no sentido de liberdade: assegurar a qualquer um a efetiva liberdade de copiá-lo ou redistribui-lo, com ou sem modificações, comercialmente ou não. Secundariamente, esta Licença mantém para o autor e editor uma forma de ter crédito por seu trabalho, sem ser considerado responsável pelas modificações feitas por terceiros. Esta Licença é um tipo de "copyleft"("direitos revertidos"), o que significa que derivações do documento precisam ser livres no mesmo sentido. Ela complementa a GNU Licença Pública Ge- ral (GNU GPL), que é um copyleft para software livre. Nós fizemos esta Licença para que seja usada em manuais de software livre, por que software livre precisa de documentação livre: um programa livre deve ser acompanhado de manuais que provenham as mesmas liberdades que o software possui. Mas esta Licença não está restrita a manuais de software; ela pode ser usada para qualquer trabalho em texto, independentemente do assunto ou se ele é publicado como um livro impresso. Nós recomendamos esta Licença prin- cipalmente para trabalhos cujo propósito seja de introdução ou referência. APLICABILIDADE E DEFINIÇÕES Esta Licença se aplica a qualquer manual ou outro texto que contenha uma nota colocada pelo detentor dos direitos autorais dizendo que ele pode ser distribuído sob os termos desta Licença. 11
  • 13. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF O "Documento"abaixo se refere a qualquer manual ou texto. Qualquer pessoa do público é um licenciado e é referida como "você". Uma "Versão Modificada"do Documento se refere a qualquer trabalho contendo o documento ou uma parte dele, quer copiada exatamente, quer com modificações e/ou traduzida em outra língua. Uma "Seção Secundária"é um apêndice ou uma seção inicial do Documento que trata ex- clusivamente da relação dos editores ou dos autores do Documento com o assunto geral do Documento (ou assuntos relacionados) e não contém nada que poderia ser incluído diretamente nesse assunto geral (Por exemplo, se o Documento é em parte um livro texto de matemática, a Seção Secundária pode não explicar nada de matemática). Essa relação poderia ser uma questão de ligação histórica com o assunto, ou matérias relaci- onadas, ou de posições legais, comerciais, filosóficas, éticas ou políticas relacionadas ao mesmo. As "Seções Invariantes"são certas Seções Secundárias cujos títulos são designados, como sendo de Seções Invariantes, na nota que diz que o Documento é publicado sob esta Licença. Os "Textos de Capa"são certos trechos curtos de texto que são listados, como Textos de Capa Frontal ou Textos da Quarta Capa, na nota que diz que o texto é publicado sob esta Licença. Uma cópia "Transparente"do Documento significa uma cópia que pode ser lida automatica- mente, representada num formato cuja especificação esteja disponível ao público geral, cujos conteúdos possam ser vistos e editados diretamente e sem mecanismos especiais com editores de texto genéricos ou (para imagens compostas de pixels) programas de pintura genéricos ou (para desenhos) por algum editor de desenhos grandemente difundido, e que seja passível de servir como entrada a formatadores de texto ou para tradução automática para uma variedade de formatos que sirvam de entrada para formatadores de texto. Uma cópia feita em um formato de arquivo outrossim Transparente cuja constituição tenha sido projetada para atrapalhar ou de- sencorajar modificações subsequentes pelos leitores não é Transparente. Uma cópia que não é "Transparente"é chamada de "Opaca". Exemplos de formatos que podem ser usados para cópias Transparentes incluem ASCII sim- ples sem marcações, formato de entrada do Texinfo, formato de entrada do LaTex, SGML ou XML usando uma DTD disponibilizada publicamente, e HTML simples, compatível com os padrões, e projetado para ser modificado por pessoas. Formatos opacos incluem PostScript, PDF, formatos proprietários que podem ser lidos e editados apenas com processadores de texto proprietários, SGML ou XML para os quais a DTD e/ou ferramentas de processamento e edição não estejam disponíveis para o público, e HTML gerado automaticamente por alguns editores de texto com finalidade apenas de saída. A "Página do Título"significa, para um livro impresso, a página do título propriamente dita, mais quaisquer páginas subsequentes quantas forem necessárias para conter, de forma legível, o material que esta Licença requer que apareça na página do título. Para trabalhos que não tenham uma página do título, "Página do Título"significa o texto próximo da aparição mais proe- minente do título do trabalho, precedendo o início do corpo do texto. 12
  • 14. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF FAZENDO CÓPIAS EXATAS Você pode copiar e distribuir o Documento em qualquer meio, de forma comercial ou não comercial, desde que esta Licença, as notas de copyright, e a nota de licença dizendo que esta Licença se aplica ao documento estejam reproduzidas em todas as cópias, e que você não acres- cente nenhuma outra condição, quaisquer que sejam, às desta Licença. Você não pode usar medidas técnicas para obstruir ou controlar a leitura ou confecção de cópias subsequentes das cópias que você fizer ou distribuir. Entretanto, você pode aceitar com- pensação em troca de cópias. Se você distribuir uma quantidade grande o suficiente de cópias, você também precisa respeitar as condições da seção 3. Você também pode emprestar cópias, sob as mesmas condições colocadas acima, e também pode exibir cópias publicamente. FAZENDO CÓPIAS EM QUANTIDADE Se você publicar cópias do Documento em número maior que 100, e a nota de licença do Documento obrigar Textos de Capa, você precisará incluir as cópias em capas que tragam, clara e legivelmente, todos esses Textos de Capa: Textos de Capa da Frente na capa da frente, e Textos da Quarta Capa na capa de trás. Ambas as capas também precisam identificar clara e legivelmente você como o editor dessas cópias. A capa da frente precisa apresentar o titulo com- pleto com todas as palavras do título igualmente proeminentes e visíveis. Você pode adicionar outros materiais às capas. Fazer cópias com modificações limitadas às capas, tanto quanto estas preservem o título do documento e satisfaçam a essas condições, pode ser tratado como cópia exata em outros aspectos. Se os textos requeridos em qualquer das capas for muito volumoso para caber de forma legível, você deve colocar os primeiros (tantos quantos couberem de forma razoável) na capa verdadeira, e continuar os outros nas páginas adjacentes. Se você publicar ou distribuir cópias Opacas do Documento em número maior que 100, você precisa ou incluir uma cópia Transparente que possa ser lida automaticamente com cada cópia Opaca, ou informar, em ou com, cada cópia Opaca a localização de uma cópia Transparente completa do Documento acessível publicamente em uma rede de computadores, a qual o público usuário de redes tenha acesso a download gratuito e anônimo utilizando padrões públicos de protocolos de rede. Se você utilizar o segundo método, você precisará tomar cuidados razoavel- mente prudentes, quando iniciar a distribuição de cópias Opacas em quantidade, para assegurar que esta cópia Transparente vai permanecer acessível desta forma na localização especificada por pelo menos um ano depois da última vez em que você distribuir uma cópia Opaca (direta- mente ou através de seus agentes ou distribuidores) daquela edição para o público. É pedido, mas não é obrigatório, que você contate os autores do Documento bem antes de redistribuir qualquer grande número de cópias, para lhes dar uma oportunidade de prover você com uma versão atualizada do Documento. 13
  • 15. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF MODIFICAÇÕES Você pode copiar e distribuir uma Versão Modificada do Documento sob as condições das se- ções 2 e 3 acima, desde que você publique a Versão Modificada estritamente sob esta Licença, com a Versão Modificada tomando o papel do Documento, de forma a licenciar a distribuição e modificação da Versão Modificada para quem quer que possua uma cópia da mesma. Além disso, você precisa fazer o seguinte na versão modificada: A. Usar na Página de Título (e nas capas, se houver alguma) um título distinto daquele do Do- cumento, e daqueles de versões anteriores (que deveriam, se houvesse algum, estarem listados na seção "Histórico do Documento"). Você pode usar o mesmo título de uma versão anterior se o editor original daquela versão lhe der permissão; B. Listar na Página de Título, como autores, uma ou mais das pessoas ou entidades responsá- veis pela autoria das modificações na Versão Modificada, conjuntamente com pelo menos cinco dos autores principais do Documento (todos os seus autores principais, se ele tiver menos que cinco); C. Colocar na Página de Título o nome do editor da Versão Modificada, como o editor; D. Preservar todas as notas de copyright do Documento; E. Adicionar uma nota de copyright apropriada para suas próprias modificações adjacente às outras notas de copyright; F. Incluir, imediatamente depois das notas de copyright, uma nota de licença dando ao público o direito de usar a Versão Modificada sob os termos desta Licença, na forma mostrada no tópico abaixo; G. Preservar nessa nota de licença as listas completas das Seções Invariantes e os Textos de Capa requeridos dados na nota de licença do Documento; H. Incluir uma cópia inalterada desta Licença; I. Preservar a seção entitulada "Histórico", e seu título, e adicionar à mesma um item dizendo pelo menos o título, ano, novos autores e editor da Versão Modificada como dados na Página de Título. Se não houver uma sessão denominada "Histórico"no Documento, criar uma dizendo o título, ano, autores, e editor do Documento como dados em sua Página de Título, então adicionar um item descrevendo a Versão Modificada, tal como descrito na sentença anterior; J. Preservar o endereço de rede, se algum, dado no Documento para acesso público a uma cópia Transparente do Documento, e da mesma forma, as localizações de rede dadas no Docu- mento para as versões anteriores em que ele foi baseado. Elas podem ser colocadas na seção "Histórico". Você pode omitir uma localização na rede para um trabalho que tenha sido publicado pelo menos quatro anos antes do Documento, ou se o editor original da versão a que ela se refira der sua permissão; K. Em qualquer seção entitulada "Agradecimentos"ou "Dedicatórias", preservar o título da 14
  • 16. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF seção e preservar a seção em toda substância e fim de cada um dos agradecimentos de contri- buidores e/ou dedicatórias dados; L. Preservar todas as Seções Invariantes do Documento, inalteradas em seus textos ou em seus títulos. Números de seção ou equivalentes não são considerados parte dos títulos da seção; M. Apagar qualquer seção entitulada "Endossos". Tal sessão não pode ser incluída na Versão Modificada; N. Não reentitular qualquer seção existente com o título "Endossos"ou com qualquer outro título dado a uma Seção Invariante. Se a Versão Modificada incluir novas seções iniciais ou apêndices que se qualifiquem como Seções Secundárias e não contenham nenhum material copiado do Documento, você pode optar por designar alguma ou todas aquelas seções como invariantes. Para fazer isso, adicione seus títulos à lista de Seções Invariantes na nota de licença da Versão Modificada. Esses títulos preci- sam ser diferentes de qualquer outro título de seção. Você pode adicionar uma seção entitulada "Endossos", desde que ela não contenha qual- quer coisa além de endossos da sua Versão Modificada por várias pessoas ou entidades - por exemplo, declarações de revisores ou de que o texto foi aprovado por uma organização como a definição oficial de um padrão. Você pode adicionar uma passagem de até cinco palavras como um Texto de Capa da Frente , e uma passagem de até 25 palavras como um Texto de Quarta Capa, ao final da lista de Textos de Capa na Versão Modificada. Somente uma passagem de Texto da Capa da Frente e uma de Texto da Quarta Capa podem ser adicionados por (ou por acordos feitos por) qualquer entidade. Se o Documento já incluir um texto de capa para a mesma capa, adicionado previamente por você ou por acordo feito com alguma entidade para a qual você esteja agindo, você não pode adicionar um outro; mas você pode trocar o antigo, com permissão explícita do editor anterior que adicionou a passagem antiga. O(s) autor(es) e editor(es) do Documento não dão permissão por esta Licença para que seus nomes sejam usados para publicidade ou para assegurar ou implicar endossamento de qualquer Versão Modificada. COMBINANDO DOCUMENTOS Você pode combinar o Documento com outros documentos publicados sob esta Licença, sob os termos definidos na seção 4 acima para versões modificadas, desde que você inclua na com- binação todas as Seções Invariantes de todos os documentos originais, sem modificações, e liste todas elas como Seções Invariantes de seu trabalho combinado em sua nota de licença. O trabalho combinado precisa conter apenas uma cópia desta Licença, e Seções Invariantes Idênticas com multiplas ocorrências podem ser substituídas por apenas uma cópia. Se houver múltiplas Seções Invariantes com o mesmo nome mas com conteúdos distintos, faça o título de 15
  • 17. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF cada seção único adicionando ao final do mesmo, em parênteses, o nome do autor ou editor origianl daquela seção, se for conhecido, ou um número que seja único. Faça o mesmo ajuste nos títulos de seção na lista de Seções Invariantes nota de licença do trabalho combinado. Na combinação, você precisa combinar quaisquer seções entituladas "Histórico"dos diver- sos documentos originais, formando uma seção entitulada "Histórico"; da mesma forma combine quaisquer seções entituladas "Agradecimentos", ou "Dedicatórias". Você precisa apagar todas as seções entituladas como "Endosso". COLETÂNEAS DE DOCUMENTOS Você pode fazer uma coletânea consitindo do Documento e outros documentos publicados sob esta Licença, e substituir as cópias individuais desta Licença nos vários documentos com uma única cópia incluida na coletânea, desde que você siga as regras desta Licença para cópia exata de cada um dos Documentos em todos os outros aspectos. Você pode extrair um único documento de tal coletânea, e distribuí-lo individualmente sob esta Licença, desde que você insira uma cópia desta Licença no documento extraído, e siga esta Licença em todos os outros aspectos relacionados à cópia exata daquele documento. AGREGAÇÃO COM TRABALHOS INDEPENDENTES Uma compilação do Documento ou derivados dele com outros trabalhos ou documentos se- parados e independentes, em um volume ou mídia de distribuição, não conta como uma Ver- são Modificada do Documento, desde que nenhum copyright de compilação seja reclamado pela compilação. Tal compilação é chamada um "agregado", e esta Licença não se aplica aos outros trabalhos auto-contidos compilados junto com o Documento, só por conta de terem sido assim compilados, e eles não são trabalhos derivados do Documento. Se o requerido para o Texto de Capa na seção 3 for aplicável a essas cópias do Documento, então, se o Documento constituir menos de um quarto de todo o agregado, os Textos de Capa do Documento podem ser colocados em capas adjacentes ao Documento dentro do agregado. Senão eles precisarão aparecer nas capas de todo o agregado. TRADUÇÃO Tradução é considerada como um tipo de modificação, então você pode distribuir traduções do Documento sob os termos da seção 4. A substituição de Seções Invariantes por traduções requer uma permissão especial dos detentores do copyright das mesmas, mas você pode incluir traduções de algumas ou de todas as Seções Invariantes em adição às versões orignais dessas Seções Invariantes. Você pode incluir uma tradução desta Licença desde que você também in- clua a versão original em Inglês desta Licença. No caso de discordância entre a tradução e a 16
  • 18. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF versão original em Inglês desta Licença, a versão original em Inglês prevalecerá. TÉRMINO Você não pode copiar, modificar, sublicenciar, ou distribuir o Documento exceto como expres- samente especificado sob esta Licença. Qualquer outra tentativa de copiar, modificar, sublicen- ciar, ou distribuir o Documento é nula, e resultará automaticamente no término de seus direitos sob esta Licença. Entretanto, terceiros que tenham recebido cópias, ou direitos de você sob esta Licença não terão suas licenças terminadas, tanto quanto esses terceiros permaneçam em total acordo com esta Licença. REVISÕES FUTURAS DESTA LICENÇA A Free Software Foundation pode publicar novas versões revisadas da Licença de Documen- tação Livre GNU de tempos em tempos. Tais novas versões serão similares em espirito à versão presente, mas podem diferir em detalhes ao abordarem novos porblemas e preocupações. Veja http://www.gnu.org/copyleft/. A cada versão da Licença é dado um número de versão distinto. Se o Documento especificar que uma versão particular desta Licença "ou qualquer versão posterior"se aplica ao mesmo, você tem a opção de seguir os termos e condições daquela versão específica, ou de qualquer versão posterior que tenha sido publicada (não como rascunho) pela Free Software Foundation. Se o Documento não especificar um número de Versão desta Licença, você pode escolher qualquer versão já publicada (não como rascunho) pela Free Software Foundation. ADENDO: Como usar esta Licença para seus documentos Para usar esta Licença num documento que você escreveu, inclua uma cópia desta Licença no documento e ponha as seguintes notas de copyright e licenças logo após a página de título: Copyright (c) ANO SEU NOME. É dada permissão para copiar, distribuir e/ou modificar este documento sob os termos da Licença de Documentação Livre GNU, Versão 1.1 ou qualquer versão posterior publicada pela Free Soft- ware Foundation; com as Seções Invariantes sendo LISTE SEUS TÍTULOS, com os Textos da Capa da Frente sendo LISTE, e com os Textos da Quarta-Capa sendo LISTE. Uma cópia da li- cença está inclusa na seção entitulada "Licença de Documentação Livre GNU". Se você não tiver nenhuma Seção Invariante, escreva "sem Seções Invariantes"ao invés de dizer quais são invariantes. Se você não tiver Textos de Capa da Frente, escreva "sem Textos de Capa da Frente"ao invés de "com os Textos de Capa da Frente sendo LISTE"; o mesmo para os Textos da Quarta Capa. Se o seu documento contiver exemplos não triviais de código de programas, nós recomenda- mos a publicação desses exemplos em paralelo sob a sua escolha de licença de software livre, 17
  • 19. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF tal como a GNU General Public License, para permitir o seu uso em software livre. 18
  • 20. Parte IV Ruby on Rails 19
  • 21. Capítulo 1 O que é o curso Ruby on Rails Ruby on Rails, ou simplismente Rails, é um framework para aplicações web desenvolvido todo na linguagem de programação Ruby. Para vocês, que estão fazendo esse curso, devem está familiarizados com essa linguagem de programação. Rails é uma ferramenta muito poderosa na hora de fazer aplicações web, como vocês poderão ver ao longo do curso. 20
  • 22. Capítulo 2 Plano de ensino 2.1 Objetivo Qualificar técnicos e programadores no framework Ruby on Rails 2.2 Público Alvo Técnicos e Programadores que desejam trabalhar com Ruby on Rails. 2.3 Pré-requisitos Os usuários deverão ser, necessariamente, indicados por empresas públicas e ter conheci- mento básico acerca da lógica de programação, HTML, Linguagem Ruby, MySQL e CSS. 2.4 Descrição O curso de Ruby on Rails será realizado na modalidade EAD e utilizará a plataforma Moodle como ferramenta de aprendizagem. Ele é composto de um módulo de aprendizado que será dado na primeira semana e um módulo de avaliação que será dado na segunda semana. O material didático estará disponível on-line de acordo com as datas pré-estabelecidas no calendário. A versão utilizada para o Ruby on Rails será a 1.1. 2.5 Metodologia O curso está dividido da seguinte maneira: 2.6 Cronograma • Lição 1 - Iniciando o Ruby on Rails; • Lição 2 - Gerando migrações e modelos de dados; 21
  • 23. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF • Lição 3 - MVC e CONTROLLER; • Lição 4 - Layouts e Roteamento; • Lição 5 - Scaffolding e Validações; • Lição 6 - Segundo controller; • Lição 7 - Extendendo um modelo de dados e Helpers. • Lição 8 - Relacionamentos; • Lição 9 - Belongs to • Lição 10 - has many, has one, e has many, through As lições contém o contéudo principal. Elas poderão ser acessadas quantas vezes forem neces- sárias, desde que esteja dentro da semana programada. Ao final de uma lição, você receberá uma nota de acordo com o seu desempenho. Responda com atenção às perguntas de cada lição, pois elas serão consideradas na sua nota final. Caso sua nota numa determinada lição for menor do que 6.0, sugerimos que você faça novamente esta lição. Ao final do curso será disponibilizada a avaliação referente ao curso. Tanto as notas das lições quanto a da avaliação serão consideradas para a nota final. Todos os módulos ficarão visíveis para que possam ser consultados durante a avaliação final. Aconselhamos a leitura da "Ambientação do Moodle"para que você conheça a plataforma de Ensino a Distância, evitando dificuldades advindas do "desconhecimento"sobre a mesma. Os instrutores estarão a sua disposição ao longo de todo curso. Qualquer dúvida deverá ser enviada no fórum. Diariamente os monitores darão respostas e esclarecimentos. 2.7 Programa O curso Ruby on Rails oferecerá o seguinte conteúdo: • Iniciando o Ruby on Rails; • Gerando migrações e modelos de dados; • MVC e CONTROLLER; • Layouts e Roteamento; • Scaffolding e Validações; • Segundo controller; • Extendendo um modelo de dados e Helpers. • Relacionamentos; • Belongs to • has many, has one, e has many, through 22
  • 24. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF 2.8 Avaliação Toda a avaliação será feita on-line. Aspectos a serem considerados na avaliação: • Iniciativa e autonomia no processo de aprendizagem e de produção de conhecimento; • Capacidade de pesquisa e abordagem criativa na solução dos problemas apresentados. Instrumentos de avaliação: • Participação ativa nas atividades programadas. • Avaliação ao final do curso. • O participante fará várias avaliações referente ao conteúdo do curso. Para a aprovação e obtenção do certificado o participante deverá obter nota final maior ou igual a 6.0 de acordo com a fórmula abaixo: • Nota Final = ((ML x 7) + (AF x 3)) / 10 = Média aritmética das lições • AF = Avaliações 2.9 Bibliografia • Site oficial: http://www.rubyonrails.org; • Rails para sua diversão e lucro. • http://forum.rubyonbr.org/forums/4/topics/2503 23
  • 25. Capítulo 3 Iniciando o Ruby on Rails Essa lição tem uma parte introdutória ao Rails e a instalação do mesmo. 3.1 Introdução Ruby on Rails é um poderoso Framework para aplicações web. O curso é voltado para desen- volvedores já familiarizados com algum ambiente de desenvolvimento Web, seja usando Linux ou Windows. Por razões de tempo, o curso assume que o desenvolvedor já tenha conhecimento de pelo menos uma linguagem de programação, de um banco de dados relacional qualquer e que seja capaz de estabelecer um ambiente para essa linguagem e banco de dados em sua plata- forma de escolha, ou seja, que tenha o conhecimento técnico para acompanhar os passos dados no curso sem maiores problemas. O curso não assume, porém, que o desenvolvedor saiba fazer o mesmo para o Rails e explica isso nos detalhes necessários. Um certo conhecimento do Ruby é requerido, embora a linguagem seja simples e poderosa o suficiente para ser inteligível para qualquer desenvolvedor com uma experiência razoável em outra linguagem de alto nível. Apesar disso, esse tutorial pode não ser tão fácil para desenvolve- dores que estejam dando os seus primeiros passos em programação e em especial programação para a Web?embora eu acredite que desenvolvedores iniciantes possam se beneficiar muito com o contato com uma linguagem mais poderosa e com um framework mais elaborado. Foi usado nesse curso o MySQL na elaboração do tutorial por ele ser um banco de fácil insta- lação, mas você pode usar o que mais se adaptar ao seu ambiente, principalmente, considerando que o Rails esconde a maior parte da complexidade nessa área e que ele suporta os principais bancos de dados existentes no mercado. Para começar, vamos assumir que você tenha um banco de dados instalado e que esteja pronto para instalar o Rails e quaisquer outras bibliotecas necessárias. Como é bom que você já tenha se familiarizado com a linguagem Ruby (seria útil que você já tenha feito o nosso curso Linguagem Ruby), a de se supor que você já tenha instalado em sua máquina o Ruby. O Ruby é uma linguagem de alto nível, tão completa quanto uma linguagem poderia ser. Sua sintaxe é bem simples, e lembra Ada e Eiffel, com algumas pitadas de Perl em alguns pontos. 3.2 Instalação Para verificar a versão instalada do Ruby, use o seguinte comando: 24
  • 26. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ronaldo@minerva: $ ruby -v ruby 1.8.4 (2005-12-24) [i486-linux] Uma vez que o Ruby esteja instalado, é hora de fazer o mesmo com o Rails. O procedimento é bem simples: Como usuário root digite: apt-get install rails Simples assim. Novas versões do Rails são instalados por um processo similar. Se você já baixou alguma versão alguma vez, use o mesmo comando acima para atualizar a sua distribuição para a versão mais recente, lembrando, principalmente, de que a versão 1.1.6 corrige um sério problema de segurança nas versões anteriores e deve ser a única usada em um servidor público. Com os passos acima finalizados e um banco de dados disponível, você está pronto para começar o desenvolvimento em Rails. A primeira coisa a fazer, então, é criar o diretório de trabalho da aplicação. Isso é feito com o comando abaixo: ronaldo@minerva: /tmp$ rails gtd create create app/controllers create app/helpers create app/models create app/views/layouts create config/environments create components create db create doc create lib create lib/tasks create log create public/images create public/javascripts create public/stylesheets create script/performance create script/process create test/fixtures create test/functional create test/integration create test/mocks/development create test/mocks/test create test/unit create vendor create vendor/plugins ... O comando rails gera o esqueleto completo de uma aplicação, pronta para rodar. Esse co- mando foi criado em seu sistema quando você instalou as bibliotecas necessárias. No esqueleto gerado, cada parte da aplicação tem um local específico para ser colocado. Isso deriva de uma das filosofias por trás do Rails que pode ser descrita pela frase ?convenção ao invés de configuração?. Convenção, nesse caso, significa que há um acordo entre o framework e você, o desenvolvedor, de modo que você não precisa de preocupar com certos detalhes que, de outra forma, teriam que se descritos em um arquivo de configuração. 25
  • 27. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF No Rails, basta executar uma determinada ação ou criar um determinado arquivo e as coi- sas funcionarão da maneira que você deseja e espera automaticamente, sem necessidade de qualquer trabalho adicional. A princípio isso pode parecer um pouco restritivo, mas na prática funciona perfeitamente. E sendo extremamente flexível, o Rails permite que você mude qualquer coisa que precise, quando precisar. Agora que temos uma aplicação básica, vamos rodá-la e ver o resultado. Uma das vantagens do Rails é que o ciclo de codificar-rodar-e-testar é bem rápido. Basta fazer uma alteração para ver imediatamente o resultado, sem a necessidade de recarregar processos, esperar a compilação da aplicação ou enviá-la para um servidor especialmente preparado. O máximo que você terá que fazer no Rails é reiniciar o servidor Web no caso de alguma mudança fundamental na configuração básica da aplicação, algo que ocorre com pouca freqüência. Para facilitar a vida, o Rails vem com seu próprio servidor Web, utilizando as bibliotecas do próprio Ruby. Para rodar o servidor, basta usar um dos scripts utilitários presentes em cada aplicação gerada pelo Rails (veja o diretório script sob o esqueleto da aplicação). O comando, executado dentro do diretório da aplicação, é o seguinte: ronaldo@minerva: /tmp/gtd$ script/server => Booting WEBrick... => Rails application started on http://0.0.0.0:3000 style="text-align: justify; font-family: courier new,courier,monospace; font-weight: bold;»=> Ctrl-C to shutdown server; call with –help for options [2006-09-20 10:31:40] INFO WEBrick 1.3.1 [2006-09-20 10:31:40] INFO ruby 1.8.4 (2005-12-24) [i486-linux] [2006-09-20 10:31:40] INFO WEBrick::HTTPServer#start: pid=8262 port=3000 Como você poder ver, o comando inicia uma instância do servidor WEBrick, capaz de servir aplicações Rails sem necessidade de qualquer configuração adicional. O servidor roda local- mente e recebe requisições na porta 3000. Sendo um servidor simples e embutido, o WEBrick não é capaz de receber requisições simultâneas, mas permite que testemos perfeitamente a nossa aplicação. Acessando o ende- reço da aplicação você tem o seguinte: 26
  • 28. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 1 Como mostrado acima, temos uma aplicação inicial rodando que, inclusive, mostra quais são os próximos passos para continuar o desenvolvimento da mesma. 3.3 Configurando Banco de Dados Vamos acatar a sugestão da página inicial e criar e configurar o banco de dados da aplica- ção. Esse primeiro passo é muito importante porque o Rails usa as informações proveniente do schema do banco de dados para gerar automaticamente arquivos e configurações adicionais. Esse é mais um exemplo de convenção ao invés de configuração. Dessa forma, garantir que o banco está funcionando corretamente, configurado para uso da aplicação, é o passo inicial de qualquer desenvolvimento em Rails. O arquivo de configuração de banco de dados se chamada database.yml e está localizado no diretório config, junto com os demais arquivos de configuração da aplicação. Esse arquivo, removendo os comentários (as linhas iniciadas com #), tem o seguinte formato Ú ÐÓÔÑ ÒØ ÔØ Ö ÑÝ×ÕÐ 27
  • 29. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ø × Ø Ú ÐÓÔÑ ÒØ Ù× ÖÒ Ñ ÖÓÓØ Ô ××ÛÓÖ Óר ÐÓ Ð Óר Ø ×Ø ÔØ Ö ÑÝ×ÕÐ Ø × Ø Ø ×Ø Ù× ÖÒ Ñ ÖÓÓØ Ô ××ÛÓÖ Óר ÐÓ Ð Óר ÔÖÓ Ù Ø ÓÒ ÔØ Ö ÑÝ×ÕÐ Ø × Ø ÔÖÓ Ù Ø ÓÒ Ù× ÖÒ Ñ ÖÓÓØ Ô ××ÛÓÖ Óר ÐÓ Ð Óר A extensao .yml se refere ao formato do arquivo, que utiliza uma linguagem de domínio cha- mada YAML. Por hora, basta saber que é uma linguagem de serialização de dados favorecida por desenvolvedores Ruby e Rails. Uma aplicação Rails geralmente utiliza três bancos de dados, como demonstrado acima, um para cada ambiente de desenvolvimento padrão. Um banco de dados é utilizado para o desen- volvimento, onde todas as mudanças são aplicadas. Esse banco tem seu correspondente em um banco de produção, onde modificações somente são aplicadas uma vez que estejam comple- tas. O arquivo permite configurar, inclusive, um banco remoto para onde suas modificações finais serão redirecionadas?embora geralmente seja melhor utilizar um outro método de implantação, como veremos mais adiante. O terceiro banco mostrado acima é um banco de testes, utilizado pelo Rails para a execução de unit testing. Esse banco deve ser mantido necessariamente à parte já que todos os dados e tabelas presentes no mesmo são excluídos e recriados a cada teste completo efetuado na aplicação. Vamos criar o banco agora: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ÑÝ×ÕÐ ¹Ù ÖÓÓØ ¹Ô ÒØ Ö Ô ××ÛÓÖ Ï Ð ÓÑ ØÓ Ø ÅÝËÉÄ ÑÓÒ ØÓÖº ÓÑÑ Ò × Ò Û Ø ÓÖ º ÓÙÖ ÅÝËÉÄ ÓÒÒ Ø ÓÒ × ØÓ × ÖÚ Ö Ú Ö× ÓÒ º¼º¾¾¹ Ò ¼Ù ÙÒØÙ º¼ º¾¹ÐÓ ÌÝÔ ³ ÐÔ ³ ÓÖ ³ ³ ÓÖ ÐÔº ÌÝÔ ³ ³ ØÓ Ð Ö Ø Ù Öº ÑÝ×ÕÐ Ö Ø Ø × Ø ÉÙ ÖÝ Çø ½ ÖÓÛ Ø ´¼º × µ ÑÝ×ÕÐ Ö Ø Ø × Ø Ø ×Ø ÉÙ ÖÝ Çø ½ ÖÓÛ Ø ´¼º ¿ × µ ÑÝ×ÕÐ Ù× Ø Ø × Ò ÑÝ×ÕÐ Modificando o arquivo de configuração para desenvolvimento local (database.yml), teríamos algo assim: 28
  • 30. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ú ÐÓÔÑ ÒØ ÔØ Ö ÑÝ×ÕÐ Ø × Ø Ù× ÖÒ Ñ ÖÓÓØ Ô ××ÛÓÖ Óר ÐÓ Ð Óר ×Ó Ø »Ú Ö»ÖÙÒ»ÑÝ×ÕÐ »ÑÝ×ÕÐ º×Ó Ø ×Ø ÔØ Ö ÑÝ×ÕÐ Ø × Ø Ø ×Ø Ù× ÖÒ Ñ ÖÓÓØ Ô ××ÛÓÖ Óר ÐÓ Ð Óר ×Ó Ø »Ú Ö»ÖÙÒ»ÑÝ×ÕÐ »ÑÝ×ÕÐ º×Ó ÔÖÓ Ù Ø ÓÒ Ú ÐÓÔÑ ÒØ No caso acima, eu configurei os banco de produção e desenvolvimento para apontarem para o mesmo local já que o desenvolvimento está limitado à minha máquina. Essa é uma estratégia interessante a usar quando queremos testar uma aplicação nas duas situações localmente sem nos preocuparmos em copiar o banco a todo momento?mesmo que o Rails permita isso com pouco mais do que alguns comandos. Eu precisei também acrescentar o método de transporte socket à configuração já que em minha máquina, especificamente, o MySQL não permite cone- xões de rede em sua configuração padrão. Outros tipos bancos de dados são configurados de maneira similar, mudando o parâmetro adapter e quaisquer outras configurações necessárias. Uma maneira mais simples de gerar uma arquivo de configuração específico para o banco de da- dos que você está usando é já invocar o comando para gerar o esqueleto da aplicação passando um parâmetro para isso. Por exemplo: rails –database=oracle gtd O comando acima gera o mesmo esqueleto da aplicação, com a única diferença de que o arquivo database.yml será um pouco diferente para levar em conta as diferenças do Oracle. Vol- tando à nossa aplicação, como um arquivo de configuração importante foi mudado, o servidor Web precisa ser reiniciado. Isso acontece porque ele somente lê essas configurações no início de execução. Esse é um dos raros casos em que um servidor de desenvolvimento precisa ser reiniciado já que o Rails recarrega praticamente qualquer modificação feita na aplicação quando está no modo de desenvolvimento. Agora temos uma aplicação e um banco de dados configurado. Com isso já podemos iniciar o processo de desenvolvimento propriamente dito. Para acesso ao banco de dados, o Rails usa classes de dados conhecidas como models, ou modelos de dados. Essas classes mascaram os detalhes ¨sórdidos¨do acesso ao banco de dados providenciando uma interface fácil e intuitiva ao desenvolvedor. Em qualquer aplicação, teremos pelo menos um modelo de dados para utilizar na mesma. E a maneira mais fácil de fazer isso é criar automaticamente a tabela no banco de dados, utilizando um dos scripts do Rails. O Rails automaticamente entende que todas as tabelas criadas no banco para uso em mode- los, ou classes de dados, satisfarão a duas condições: terão um nome plural em inglês e terão 29
  • 31. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF uma chave primária surrogada inteira e auto-incrementada chamada id. É possível mudar ambas as condições, mas inicialmente ficaremos com elas para não ter que modificar o que o Rails gera e usa automaticamente. Para facilitar o desenvolvimento, a aplicação desenvolvida está em inglês, que espero seja simples o suficiente mesmo para a compreensão do leitor que não domine plenamente este idi- oma. Considerando a profusão de termos em inglês em nossa área acho que isso não será um problema. O uso do inglês evita que tenhamos que pensar em alguns detalhes de tradução e globalização enquanto estamos aprendendo o Rails. Mais no fim do tutorial explicaremos como mudar algumas das coisas que o Rails por como padrão. 30
  • 32. Capítulo 4 Gerando Migrações e Modelos de Dados Essa lição tem como objetivo mostrar como alterar qualquer natureza no banco de dados. 4.1 Gerando Migrações e Modelos de dados I Para manter portabilidade e facilitar o controle de versionamento do banco de dados, o Rails utiliza algo chamado migrations (migrações). São scripts em Ruby descrevendo modificações de qualquer natureza no banco de dados. Migrações são a maneira mais fácil de acrescentar tabelas e classes de dados ao Rails e é o que utilizaremos agora. A primeira tabela que vamos criar será a tabela de contextos. Contextos, no GTD, são, basicamente, os ambientes onde uma ação será executada, como, por exemplo, casa, escritório, e-mail, telefone, etc. Vamos gerar então uma migração para essa primeira modificação no banco: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» Ò Ö Ø Ñ Ö Ø ÓÒ Ö Ø ÓÒØ ÜØ× Ö Ø »Ñ Ö Ø Ö Ø »Ñ Ö Ø »¼¼½ Ö Ø ÓÒØ ÜØ×ºÖ O script generate é uma das ferramentas cruciais do Rails que utilizaremos ao longo de todo nosso curso, sendo usado, como o nome indica, para criar basicamente qualquer estrutura que precisamos em uma aplicação. O seu primeiro parâmetro é o tipo de objeto que estamos ge- rando, seu segundo parâmetro é o nome desse objeto e quaisquer outros parâmetro adicionais indicam opções de geração. No caso acima, estamos gerando uma migração, cujo nome é cre- ate_contexts. No Rails, existem muitas convenções quanto ao uso de nomes, que são seguidas pelos comandos do mesmo, com conversões automáticas quando necessário. No caso acima, por exemplo, o nome que usamos será automaticamente convertido em um nome de classe, que no Ruby são expressas com capitalização alternada, como você poderá ver abaixo. O resultado do comando é um arquivo novo, prefixado pela versão da migração, que foi criado no diretório db/migrate. Esse prefixo é usado para controlar quais alterações um banco precisa sofrer para chegar a uma versão específica. Editando o arquivo, temos o seguinte: Ð ×× Ö Ø ÓÒØ ÜØ× Ø Ú Ê ÓÖ Å Ö Ø ÓÒ × Ð ºÙÔ 31
  • 33. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ò × Ð º ÓÛÒ Ò Ò O Rails criou uma classe derivada () da classe ActiveRecord::Migration com dois métodos. Esses métodos, por estarem prefixados por self, indicam no Ruby que os mesmos podem ser chamados diretamente na classe (métodos estáticos na terminologia do C++, C# e do Java), sem necessidade de uma instância. O método self.up é utilizado para efetuar as modificações. O seu oposto, self.down, é usado para desfazer essas modificações caso você esteja revertendo para uma versão anterior do banco. Dependendo da forma como os métodos forem escritos, eles serão realmente complementares. Obviamente é possível que modificações sejam efetuadas que não são reversíveis. Nesse caso, o Rails emitirá um erro se uma migração para uma versão mais baixa for tentada. Vamos editar o arquivo agora para incluir a tabela que desejamos criar: Ð ×× Ö Ø ÓÒØ ÜØ× Ø Ú Ê ÓÖ Å Ö Ø ÓÒ × Ð ºÙÔ Ö Ø Ø Ð ÓÒØ ÜØ× Ó Ø Øº ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò Ò Ò × Ð º ÓÛÒ ÖÓÔ Ø Ð ÓÒØ ÜØ× Ò Ò Para efetuar suas migrações, o Rails utiliza uma linguagem de domínio que permite especificar operações de banco de dados de forma abstrata, que não está presa a um servidor específico. É possível executar operações diretamente via SQL no banco, mas isso não é recomendado por quebrar essa abstração. No caso acima, o método create_table dentro de self.up serve para especificar a tabela que será criada. Esse método recebe um bloco como parâmetro (indicado pela palavra-chave do) que especifica as colunas que serão adicionadas. Blocos são uma das partes mais interessantes do Ruby e vale a estudar um pouco o que eles podem fazer já que o uso dos mesmos é extenso em qualquer aplicação na linguagem, incluindo o Rails. No Ruby, os blocos são valores de primeira classe, que pode ser atribuídos e manipulados como qualquer outro objeto. Um outro detalhe a manter em mente é o uso extensivo de símbolos no Ruby. No caso acima, o próprio nome da tabela é denotado por um símbolo. Símbolos são similares a strings, com a diferença fundamental que são internalizados e existem com uma única instância que permite um uso transparente e eficiente dos mesmos. Voltando ao nosso código, como a tabela terá somente uma coluna inicialmente, que é o nome do contexto, somente precisamos de uma linha, identificando o nome da coluna e seu tipo. Mais à frente veremos outros tipos e opções. O método self.down, como explicando, realiza a operação inversa destruindo a tabela. Agora é hora de aplicar essa migração ao banco, subindo sua versão. Para isso, temos o utilitário rake, que é parte do Ruby. O rake é o equivalente Ruby do make, sendo capaz de realizar tarefas descritas em um Rakefile, da mesma forma que o make faz uso de um Makefile. O Rails 32
  • 34. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF vem com seu próprio Rakefile que permite a execução de várias de suas tarefas necessárias, incluindo db:migrate, que aplica as migrações ainda não efetuadas a um banco. Rodamos o comando da seguinte forma: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° Ö Ñ Ö Ø ´ Ò »ØÑÔ» Ø µ Ö Ø ÓÒØ ÜØ× Ñ Ö Ø Ò ¹¹ Ö Ø Ø Ð ´ ÓÒØ ܨ׵ ¹ ½º¾¼ × Ö Ø ÓÒØ ÜØ× Ñ Ö Ø ´½º¾¼ ¾×µ Se observamos o banco agora, teremos o seguinte schema: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ÑÝ×ÕÐ ¹Ù ÖÓÓØ ¹Ô Ø ÑÝ×ÕÐ × ÓÛ Ø Ð × ·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· Ì Ð × Ò Ø ·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· ÓÒØ ÜØ× × Ñ Ò Ó ·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· ¾ ÖÓÛ× Ò × Ø ´¼º¼¼ × µ Duas tabelas foram criadas, contexts e schema_info. A primeira é a que especificamos. A segunda descreve informações do banco para o Rails, para controlar o versionamento do mesmo. A tabela contexts ficou assim: Ó ÒÚÑ »ØÑÔ» Ø ° ÑÝ×ÕÐ ¹Ù ÖÓÓØ ¹Ô ÑÝ×ÕÐ × Ö ÓÒØ ÜØ× ·¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· Ð ÌÝÔ ÆÙÐÐ Ã Ý ÙÐØ ÜØÖ ·¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· ÒØ´½½µ ÆÇ ÈÊÁ ÆÍÄÄ ÙØÓ Ò Ö Ñ ÒØ Ò Ñ Ú Ö Ö´¾ µ Ë ÆÍÄÄ ·¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· ¾ ÖÓÛ× Ò × Ø ´¼º¼¼ × µ Como você pode ver, não é preciso especificar a chave primária surrogada, que é automati- camente criada pelo Rails. A tabela schema_info possui os seguintes dados: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ÑÝ×ÕÐ ¹Ù ÖÓÓØ ¹Ô Ø ÑÝ×ÕÐ × Ð Ø ¶ ÖÓÑ × Ñ Ò Ó ·¹¹¹¹¹¹¹¹¹· Ú Ö× ÓÒ ·¹¹¹¹¹¹¹¹¹· ½ ·¹¹¹¹¹¹¹¹¹· ½ ÖÓÛ Ò × Ø ´¼º¼¼ × µ 33
  • 35. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Esse número de versão será incrementado ou decrementado dependendo da direção da mi- gração. A migração também criou o arquivo db/schema.rb, contendo uma representação do banco em Ruby, que pode ser usada para recriar a estrutura do mesmo em qualquer banco suportado pelo Rails, usando uma outra tarefa do rake. O arquivo é auto-gerado e não deve ser modificado manualmente. Seu formato pode ser visto abaixo: Ì × Ð × ÙØÓ Ò Ö Ø º ÁÒר Ó Ø Ò Ø × Ð ¸ ÔÐ × Ù× Ø Ñ Ö Ø ÓÒ× ØÙÖ Ó Ø Ú Ê ÓÖ ØÓ Ò Ö Ñ ÒØ ÐÐÝ ÑÓ Ý ÝÓÙÖ Ø × ¸ Ò Ø Ò Ö Ò Ö Ø Ø × × Ñ Ò Ø ÓÒº Ø Ú Ê ÓÖ Ë Ñ º Ò ´ Ú Ö× ÓÒ ½µ Ó Ö Ø Ø Ð ÓÒØ ÜØ× ¸ ÓÖ ØÖÙ Ó Ø Øº ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò Ò Ò Note apenas que essa representação é limitada às tabelas em si e não inclui chaves es- trangeiras, triggers ou stored procedures. O próximo passo agora é criar a classe de dados correspondente à tabela. Para isso, usamos o comando abaixo: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» Ò Ö Ø ÑÓ Ð ÓÒØ ÜØ Ü ×Ø× ÔÔ»ÑÓ Ð×» Ü ×Ø× Ø ×Ø»ÙÒ Ø» Ü ×Ø× Ø ×Ø» ÜØÙÖ ×» Ö Ø ÔÔ»ÑÓ Ð×» ÓÒØ ÜØºÖ Ö Ø Ø ×Ø»ÙÒ Ø» ÓÒØ ÜØ Ø ×ØºÖ Ö Ø Ø ×Ø» ÜØÙÖ ×» ÓÒØ ÜØ×ºÝÑÐ Ü ×Ø× »Ñ Ö Ø ÒÓØ Ö Ñ Ö Ø ÓÒ × ÐÖ Ý Ò Ñ Ö Ø ÓÒØ ÜØ× »Ñ Ö Ø »¼¼½ Ö Ø ÓÒØ ÜØ×ºÖ O Rails utiliza uma estratégia de desenvolvimento (conhecidas como patterns de maneira geral) chamada de MVC (Model-View-Controller). Essa estratégia separa os componentes da aplicação em partes distintas que não só facilitam o desenvolvimento como também facilitam a manutenção. O que estamos vendo no momento são os models, que correspondem à camada de acesso ao banco de dados, implementada no Rails por um componente denominado ActiveRe- cord. O comando acima gera toda estrutura de suporte ao modelo, incluindo testes e migrações para o mesmo. Como geramos a nossa migração inicial manualmente, o Rails nos informa que já existe uma com o mesmo nome que ele pretendia gerar e que ele está pulando esse passo. O arquivo responsável pela implementação do modelo está em app/model/context.rb e contém apenas o seguinte: Ð ×× ÓÒØ ÜØ Ø Ú Ê ÓÖ × Ò Essas duas linhas, apoiadas pelo Rails, já providenciam uma riqueza de implementação que nos permite recuperar, inserir e atualizar dados no banco, e executar uma série de outras opera- ções complexas sem a necessidade de qualquer comando SQL direto. Vamos criar agora um novo modelo correspondendo à tabela de projetos. Vamos deixar que o Rails gere a migração dessa vez. O comando é: 34
  • 36. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» Ò Ö Ø ÑÓ Ð ÔÖÓ Ø Ü ×Ø× ÔÔ»ÑÓ Ð×» Ü ×Ø× Ø ×Ø»ÙÒ Ø» Ü ×Ø× Ø ×Ø» ÜØÙÖ ×» Ö Ø ÔÔ»ÑÓ Ð×»ÔÖÓ ØºÖ Ö Ø Ø ×Ø»ÙÒ Ø»ÔÖÓ Ø Ø ×ØºÖ Ö Ø Ø ×Ø» ÜØÙÖ ×»ÔÖÓ Ø×ºÝÑÐ Ü ×Ø× »Ñ Ö Ø Ö Ø »Ñ Ö Ø »¼¼¾ Ö Ø ÔÖÓ Ø×ºÖ Você pode ver que o Rails gerou um template da migração, e basta editá-la: Ð ×× Ö Ø ÈÖÓ Ø× Ø Ú Ê ÓÖ Å Ö Ø ÓÒ × Ð ºÙÔ Ö Ø Ø Ð ÔÖÓ Ø× Ó Ø Øº ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò Ò Ò × Ð º ÓÛÒ ÖÓÔ Ø Ð ÔÖÓ Ø× Ò Ò O arquivo final seria, com base no que pensamos até o momento: Ð ×× Ö Ø ÈÖÓ Ø× Ø Ú Ê ÓÖ Å Ö Ø ÓÒ × Ð ºÙÔ Ö Ø Ø Ð ÔÖÓ Ø× Ó Ø Øº ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò Øº ÓÐÙÑÒ × Ö ÔØ ÓÒ¸ Ø ÜØ Ò Ò × Ð º ÓÛÒ ÖÓÔ Ø Ð ÔÖÓ Ø× Ò Ò Você não precisa se preocupar em criar todos os campos inicialmente. Você pode sempre usar outra migração para isso. Rodando o comando rake para carregar as migrações mais uma vez, temos o seguinte: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° Ö Ñ Ö Ø ´ Ò » ÓÑ »ÖÓÒ Ð Ó»ØÑÔ» Ø µ Ö Ø ÈÖÓ Ø× Ñ Ö Ø Ò ¹¹ Ö Ø Ø Ð ´ ÔÖÓ Ø×µ ¹ ¼º½ ¿× Ö Ø ÈÖÓ Ø× Ñ Ö Ø ´¼º½ ×µ O resultado final do banco seria: 35
  • 37. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° ÑÝ×ÕÐ ¹Ù ÖÓÓØ ¹Ô Ø ÑÝ×ÕÐ × ÓÛ Ø Ð × ·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· Ì Ð × Ò Ø ·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· ÓÒØ ÜØ× ÔÖÓ Ø× × Ñ Ò Ó ·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· ¿ ÖÓÛ× Ò × Ø ´¼º¼¼ × µ ÑÝ×ÕÐ × Ö ÔÖÓ Ø× ·¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· Ð ÌÝÔ ÆÙÐÐ Ã Ý ÙÐØ ÜØÖ ·¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· ÒØ´½½µ ÆÇ ÈÊÁ ÆÍÄÄ ÙØÓ Ò Ö Ñ ÒØ Ò Ñ Ú Ö Ö´¾ µ Ë ÆÍÄÄ × Ö ÔØ ÓÒ Ø ÜØ Ë ÆÍÄÄ ·¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹·¹¹¹¹¹·¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹· ¿ ÖÓÛ× Ò × Ø ´¼º¼¼ × µ ÑÝ×ÕÐ × Ð Ø ¶ ÖÓÑ × Ñ Ò Ó ·¹¹¹¹¹¹¹¹¹· Ú Ö× ÓÒ ·¹¹¹¹¹¹¹¹¹· ¾ ·¹¹¹¹¹¹¹¹¹· ½ ÖÓÛ Ò × Ø ´¼º¼¼ × µ E o arquivo db/schema.rb agora contém: Ì × Ð × ÙØÓ Ò Ö Ø º ÁÒר Ó Ø Ò Ø × Ð ¸ ÔÐ × Ù× Ø Ñ Ö Ø ÓÒ× ØÙÖ Ó Ø Ú Ê ÓÖ ØÓ Ò Ö Ñ ÒØ ÐÐÝ ÑÓ Ý ÝÓÙÖ Ø × ¸ Ò Ø Ò Ö Ò Ö Ø Ø × × Ñ Ò Ø ÓÒº Ø Ú Ê ÓÖ Ë Ñ º Ò ´ Ú Ö× ÓÒ ¾µ Ó Ö Ø Ø Ð ÓÒØ ÜØ× ¸ ÓÖ ØÖÙ Ó Ø Øº ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò Ò Ö Ø Ø Ð ÔÖÓ Ø× ¸ ÓÖ ØÖÙ Ó Ø Øº ÓÐÙÑÒ Ò Ñ ¸ ×ØÖ Ò Øº ÓÐÙÑÒ × Ö ÔØ ÓÒ ¸ Ø ÜØ Ò Ò Para terminar, vamos gerar a tabela e o modelo de ações: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» Ò Ö Ø ÑÓ Ð Ø ÓÒ Ü ×Ø× ÔÔ»ÑÓ Ð×» Ü ×Ø× Ø ×Ø»ÙÒ Ø» 36
  • 38. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ü ×Ø× Ø ×Ø» ÜØÙÖ ×» Ö Ø ÔÔ»ÑÓ Ð×» Ø ÓÒºÖ Ö Ø Ø ×Ø»ÙÒ Ø» Ø ÓÒ Ø ×ØºÖ Ö Ø Ø ×Ø» ÜØÙÖ ×» Ø ÓÒ׺ÝÑÐ Ü ×Ø× »Ñ Ö Ø Ö Ø »Ñ Ö Ø »¼¼¿ Ö Ø Ø ÓÒ×ºÖ A migração para o modelo seria: Ð ×× Ö Ø Ø ÓÒ× Ø Ú Ê ÓÖ Å Ö Ø ÓÒ × Ð ºÙÔ Ö Ø Ø Ð Ø ÓÒ× Ó Ø Øº ÓÐÙÑÒ × Ö ÔØ ÓÒ¸ ×ØÖ Ò Øº ÓÐÙÑÒ ÓÒ ¸ ÓÓÐ Ò Øº ÓÐÙÑÒ Ö Ø Ø¸ Ø Ø Ñ Øº ÓÐÙÑÒ ÓÑÔÐ Ø Ø¸ Ø Ø Ñ Øº ÓÐÙÑÒ ÓÒØ ÜØ ¸ ÒØ Ö Øº ÓÐÙÑÒ ÔÖÓ Ø ¸ ÒØ Ö Ò Ò × Ð º ÓÛÒ ÖÓÔ Ø Ð Ø ÓÒ× Ò Ò Com isso, já temos agora o suficiente em nosso banco de dados para trabalhar um pouco em nossa aplicação. Um recurso muito útil do Rails é o console, que serve tanto para experimentar com as clas- ses de dados como para executar uma série de outras funções úteis de teste e manutenção da aplicação. Para acessar o controle, use o seguinte comando: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» ÓÒ×ÓÐ ÄÓ Ò Ú ÐÓÔÑ ÒØ ÒÚ ÖÓÒÑ ÒØº Obs.: Para executar esse comando é necessário que você tenha instalado o pacote irb. A exemplo de um console de comando do DOS ou do próprio MySQL, o console do Rails permite que você insira um comando e veja seus resultados imediatamente: Por exemplo: ÓÒØ ÜØº Ö Ø ´ Ò Ñ ³ÀÓÑ ³µ ÓÒØ ÜØ ¼Ü ¿ Ò Û Ö ÓÖ Ð× ¸ ÖÖÓÖ× Ø Ú Ê ÓÖ ÖÖÓÖ× ¼Ü × ÓÒØ ÜØ ¼Ü ¿ ººº ¸ ÖÖÓÖ× ß ¸ ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½ O comando acima cria e salva um novo contexto, recebendo como parâmetro o nome do mesmo, descrito por seu único atributo. O resultado, visto logo depois do comando, é uma repre- sentação textual da classe. Todos objetos em Ruby, e isso inclui desde números inteiros a classe complexas, possuem uma representação textual. Na maior parte dos casos, o Ruby gera uma representação textual 37
  • 39. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF automática para classes que não especificam a sua própria representação e é isso o que você está vendo acima. Em uma aplicação, você provavelmente precisará criar um objeto e manipulá-lo antes de salvá-lo. Isso também é possível, como demonstrado abaixo: ÓÒØ ÜØ ÓÒØ ÜØºÒ Û ÓÒØ ÜØ ¼Ü ½ ¼ Ò Û Ö ÓÖ ØÖÙ ¸ ØØÖ ÙØ × ß Ò Ñ Ò Ð ÓÒØ ÜØºÒ Ñ ³ÏÓÖ ³ ÏÓÖ ÓÒØ ÜØº× Ú ØÖÙ No exemplo acima, o objeto é criado, uma de suas propriedade é atribuída e depois disso o objeto é salvo. A persistência de dados só ocorre na invocação do método save. Outras operações são possíveis: ÓÒØ ÜØº Ò ´ Ðе ÓÒØ ÜØ ¼Ü ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½ ¸ ÓÒØ ÜØ ¼Ü ØØÖ ÙØ × ß Ò Ñ ÏÓÖ ¸ ¾ ℄ ÓÒØ ÜØº Ò ´¾µ ÓÒØ ÜØ ¼Ü ¾¿¾ ØØÖ ÙØ × ß Ò Ñ ÏÓÖ ¸ ¾ ÓÒØ ÜØº Ò ´ Öר¸ ÓÒ Ø ÓÒ× ³Ò Ñ Ð ³¸ ³ÀÓÑ ³℄µ ÓÒØ ÜØ ¼Ü ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½ A primeira chamada acima retorna todos os registros correspondente aos contextos. Vemos que o resultado é um array, delimitado por []. A segunda chamada, por sua vez, retorna o objeto especificado pelo id passado, ou seja, por sua chave primária surrogada. O terceiro método, por fim, retorna o primeiro registro satisfazendo as condições passadas. O método find possui vários outros parâmetros que servem para gerar queries complexas sem esforço, ordenando o resultado, limitando a quantidade de itens retornados, e, para usos mais avançados, criando joins automaticamente. Veremos exemplos extensos disso mais adiante. A sofisticação das classes geradas pelo ActiveRecord se estende ao ponto da criação de métodos automáticos para várias situações. Algumas delas exploraremos depois, mas vale a pena notar aqui pelo menos uma delas: métodos de busca e criação automáticos. Por exemplo, é possível executar o comando abaixo para encontrar um contexto pelo seu nome: ÓÒØ ÜØº Ò Ý Ò Ñ ´³ÀÓÑ ³µ ÓÒØ ÜØ ¼Ü ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½ O método find_by_name não existia até ser chamado. Isso pode ser visto verificando a exis- tência do método, usando respond_to?, que é um método presente em todas as classes Ruby e, ao receber um símbolo que especifica o nome do método a ser testado, devolve uma valor indicando se a classe suporta o método ou não: ÓÒØ ÜØºÖ ×ÔÓÒ ØÓ ´ Ò Ý Ò Ñ µ 38
  • 40. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ð× ÓÒØ ÜØº Ò Ý Ò Ñ ´³ÀÓÑ ³µ ÓÒØ ÜØ ¼Ü ¼ ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½ Como é fácil perceber, a classe não possui aquele método até que ele seja invocado. Uma classe de dados Rails aceita combinações quaisquer de seus atributos e de algumas operações para gerar esse tipo de métodos. Um exemplo é find_or_create_by_name, que procuraria um registro e o criaria caso não fosse encontrado, com o nome passado como parâmetro. Se a classe possuir mais atribu- tos, poderíamos muito bem usar algo como find_or_create_by_name_and_description ou ainda find_by_description_and_completed_at. É claro que se usarmos isso para todas as chamadas, teremos métodos com nomes absurda- mente longos como find_or_create_by_description_and_created_at_and_completed_at_and_done que ficariam bem melhor como chamadas separadas usando condições por questões de legibili- dade. O que estamos fazendo aqui no console é basicamente o que faremos em uma aplicação no que tange à manipulação de dados. Como você pode ver, na maior parte dos casos, o Rails não exige que o desenvolvedor escreva código SQL, gerando o código necessário por trás das cenas, com toda eficiência possível. E caso seja necessário, há ainda duas possilidades: usar parâmetros mais avançados do método find, que permitem a inserção de fragmentos de SQL em uma operação qualquer; ou ainda, usar métodos como find_by_sql que permitem um execução direta no banco com integração plena com o Rails. Usar as facilidades do Rails não significa que o desenvolvedor não precisa conhecer SQL; ao contrário, o conhecimento é fundamental, tanto para evitar problemas no uso do próprio Rails como para todas outras tarefas que existem além do Rails. Agora que já trabalhamos um pouco com o modelo de dados, vamos passar para a aplicação em si. 39
  • 41. Capítulo 5 MVC e CONTROLLER Essa lição tem como objetivo explicar o que se trata o MVC e como fazer o primeiro CON- TROLLER 5.1 MVC Como mencionado anteriormente, o Rails utilizado a estratégia MVC. A parte correspondente ao Model existe nas classes de dados e é implementada pelo ActiveRecord. Um segundo compo- nente do Rails, o ActionPack, implementa o V e o C que são respectivamente View e Controller. Um controller é uma classe responsável por receber as requisições feitas pela aplicação e executar as ações necessárias para atender essas requisições. Essas ações, ao serem executa- das, provavelmente causarão mudanças no banco que serão efetuadas, por sua vez, por uma ou mais classes de dados. Finalmente, o resultado será exibido através de uma view, que será retornada ao usuário na forma de HTML, imagens, XML, ou qualquer outra saída aceitável da aplicação. As três partes da estratégia MVC são independentes no Rails como deveriam ser em qual- quer boa implementação das mesmas. Qualquer modelo de dados pode ser utilizado indepen- dentemente, inclusive em scripts que não tem a ver com a aplicação Web em si, como, por exemplo, tarefas agendadas. Os controllers também são independentes e podem ser usado para simplesmente efetuar ações que nem mesmo retornam views, atualizando somente o banco ou disparando outro processo qualquer no servidor. As views são, de certa forma, a parte mais de- pendente já que, embora podendo ser utilizadas separadamente, não fazem muito sentido sem utilizarem dados gerados por modelos de dados e controllers. Para identificar qual controller será responsável por atender uma determinada solicitação da aplicação, o Rails utiliza uma mecanismo de roteamento de requisições automático que não ne- cessita de configurações complexas, mas que pode também ser customizado de acordo com as necessidades de cada aplicação. A regra principal de roteamento no Rails forma URLs segundo o padrão /controller/action/id, onde controller é a classe responsável por atender a requisição especificada por aquela URL, action é um método dentro da classe e id é um parâmetro opcional passado para identificar um objeto qualquer sobre o qual a ação será efetuada. Como dito anteriormente, esse padrão pode ser modificado e veremos mais sobre isso adiante no tutorial. 40
  • 42. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF 5.2 O primeiro controller Vamos começar criando um controller para lidar com a página inicial de nossa aplicação. Para gerar um controller, usamos o comando abaixo: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» Ò Ö Ø ÓÒØÖÓÐÐ Ö ÓÑ Ü ×Ø× ÔÔ» ÓÒØÖÓÐÐ Ö×» Ü ×Ø× ÔÔ» ÐÔ Ö×» Ö Ø ÔÔ»Ú Û×» ÓÑ Ü ×Ø× Ø ×Ø» ÙÒ Ø ÓÒ Ð» Ö Ø ÔÔ» ÓÒØÖÓÐÐ Ö×» ÓÑ ÓÒØÖÓÐÐ ÖºÖ Ö Ø Ø ×Ø» ÙÒ Ø ÓÒ Ð» ÓÑ ÓÒØÖÓÐÐ Ö Ø ×ØºÖ Ö Ø ÔÔ» ÐÔ Ö×» ÓÑ ÐÔ ÖºÖ O nome passado para o comando é home, que será usado para compor todos os arquivos gerados pelo mesmo. Da mesma forma que nos modelos de dados, o Rails cria unit tests para a classe gerada, que podem ser executados com o comando rake tests. Esse comando roda todos os unit tests presentes na aplicação e qualquer boa aplicação desenvolvida segundo a metodologia Extreme Programming faz uso extensivo dessa técnica. Veremos esse assunto em mais detalhes em uma outra seção de nosso tutorial. Se você acessar a URL desse controller agora, você vai receber a seguinte tela: Figura 2 41
  • 43. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Repare que, nesse caso, eu informei somente /controller/ como a URL, sem passar nem a parte correspondente a uma ação ou a um id. Nesse caso, o Rails assume que estamos invocando a ação index sem id. Esse é um mais exemplo de convenção ao invés de configuração. Ao invés de ter sempre que especificar uma ação padrão em algum lugar, o Rails convenciona que a ação padrão é index, poupando o desenvolvedor sem afetar a aplicação. Vamos olhar o arquivo app/controllers/home_controller.rb gerado por nosso comando. Como já mencionamos, o Rails segue uma estrutura fixa de diretórios, poupando mais uma vez o de- senvolvedor. Arquivos relacionados ao banco vão em no diretório db, arquivos de configuração em config e tudo relacionado a MVC vai em app. Dentro de app temos vários outros diretórios que contém mais partes específicas da aplicação. Em alguns casos, o Rails também adiciona um sufixo ao arquivo, evitando colisões de nomes e problemas estranhos na aplicação, como é o caso aqui. O arquivo do controller criado contém o seguinte: Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò A classe HomeController define quem que irá responder a requisições padrão em /home. Ela herda da classe ApplicationController, que está definida no arquivo application.rb, no mesmo diretório. Sendo assim, qualquer método criado na classe ApplicationController estará automati- camente disponível nos controllers gerados para a aplicação. O uso de herança serve mais uma vez para beneficiar o desenvolvedor que pode utilizar um modelo mental familiar para trabalhar sua aplicação, um modelo que é ao mesmo tempo simples e poderoso. Para criarmos a ação index, basta adicionarmos um método à classe: Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ò Ò O princípio que usamos acima é comum a tudo em Rails. Basicamente tudo o que fazemos em uma aplicação usando o mesmo consiste em extender alguma classe por meio da adição de métodos customizados. Recarregando a página no navegador, ficamos com o seguinte: 42
  • 44. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 3 Vamos que, dessa vez, o Rails identificou a ação a ser executada, mas, como a aplicação não especificou nenhum retorno, houve um erro. Isso aconteceu porque o Rails tentou aplicar automaticamente uma view para aquela ação do controller. Como a view ainda não existe, temos o erro. Antes de nos aventurarmos em uma view usando o mecanismo de templates do Rails, vamos retornar algum texto por contra própria: Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ö Ò Ö Ø ÜØ ÇÐ Ò Ò O método render, disponível para qualquer controller ou view, gera saída na aplicação, saída esta que depende de seus parâmetros. No caso acima, estamos renderizando texto puro, como indicado pelo parâmetro text. Nossa página agora ficaria assim: 43
  • 45. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 4 Temos a nossa primeira saída em uma aplicação Rails. Como escrever manualmente toda a saída não é o que queremos, vamos criar a nossa pri- meira view. Para isso, criamos o arquivo app/views/home/index.rhtml. A extensão .rhtml indica que esse arquivo contém HTML e código Ruby. Uma outra extensão possível seria .rjs para gerar retorno em JavaScript, comumente utilizado em aplicações Ajax. Há ainda .rxml, para gerar saída em XML. Outros mecanismos de tem- plate podem usar outras extensões, já que o Rails pode ser configurado para outros mecanismos alternativos. Por hora, usaremos a linguagem de templates padrão do Rails. Vamos criar o seguinte ar- quivo, então: Ô ÇÐ ¸ ÑÙÒ Ó »Ô Se recarregamos a página, notaremos que nada mudou. Isso acontece porque estamos usando render diretamente. Nesse caso, o Rails detecta que alguma saída já foi gerada e não tenta gerar outra. Basta, então, remover a chamada a render método index, voltando o arquivo a: Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö 44
  • 46. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ò Ü Ò Ò Agora, recarregando a página, temos: Figura 5 Sem que haja necessidade de especificar qualquer coisa, o Rails está usando o arquivo ade- quado. Veja que não configuramos qualquer coisa. Criamos um controller, definimos um método no mesmo, e criamos um arquivo que contém o que queremos que seja retornado por aquele método. A simples existência desses arquivos representa uma cadeia de execução sem que precisamos nos preocupar com que parte da aplicação faz isso ou aquilo. Qualquer outra ação que fosse criada dentro desse controller seguiria o mesmo padrão. O nome da ação seria associado a um nome de arquivo dentro de um diretório em app/views cujo nome seria o do próprio controller. O Rails também é inteligente ao ponto de responder a uma ação mesmo que o método não exista, desde que a view esteja presente no diretório correto. 45
  • 47. Capítulo 6 Layouts e Roteamento Essa lição tem como finalidade facilitar o desenvolvimento da parte visual de uma aplicação. Para isso, o Rails possui um conceito denominado layouts. E o roteamento é para satisfazer a URL que foi especificada. 6.1 Layouts Na maioria das aplicações Web, as páginas variam somente no seu conteúdo principal, pos- suindo cabeçalhos, rodapés e barras de navegação em comum. Obviamente, um framework cujo maior objetivo é aumentar a produtividade do desenvolvedor não exigiria que o código para esses elementos tivesse que ser repetido em cada view. Um layout funciona como um arquivo raiz, dentro do qual o resultado de uma view é inserido automaticamente. Mais uma vez favorecendo convenção ao invés de configuração, o Rails define um arquivo pa- drão de layout que é usado automaticamente por qualquer view a não ser que haja especificação em contrário. O Rail também é inteligente o bastante para somente usar um layout em views com a mesma extensão. O layout padrão para a aplicação fica em um arquivo chamado application.rhtml, dentro do diretóri app/views/layouts, que não existe ainda. Se você olhar agora o código gerado pela página que criamos até o momento, você verá o seguinte: 46
  • 48. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 6 Como você pode notar, ão estamos gerando nenhum dos elementos HTML geralmente vistos em uma página comum. Vamos criar o arquivo application.rhtml no diretório especificado, com o seguinte conteúdo: ØÑÐ Ø ØÐ Ì »Ø ØÐ » Ó Ý ± Ý Ð ± » Ó Ý » ØÑÐ Temos no arquivo acima, o primeiro exemplo de uso de código Ruby dentro de uma view, delimitado pelos marcadores % e %. Aqueles familiarizados com PHP e ASP reconhecerão o estilo de marcadores, com o uso de %= objeto % para retornar conteúdo. No caso acima, o método especial yield retorna o conteúdo atual gerado pela ação, seja por meio de uma view ou usando render diretamente. O método yield tem uma conotação especial 47
  • 49. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF no Ruby, servindo para invocar o bloco associado ao contexto. Inserido em um layout do Rails, o bloco define a execução da ação, com seu conseqüente retorno de conteúdo. A nossa página recarregada agora fica como mostrado abaixo: Figura 7 Não parece muita coisa, mas, olhando o código, você verá o seguinte: 48
  • 50. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 8 É fácil perceber que o código do layout foi aplicado sobre o código da view, gerando a saída final da aplicação. O que precisamos fazer agora é extender o nosso layout para incluir algumas amenidades. O nosso arquivo application.rhtml poderia ser mudado para o seguinte: ØÑÐ Ø ØÐ Ì »Ø ØÐ ± רÝÐ × Ø Ð Ò Ø ÙÐØ ± » Ó Ý ± Ý Ð ± » Ó Ý » ØÑÐ O método stylesheet_link_tag recebe o nome de uma stylesheet como parâmetro e gera um link para a mesma. O nosso código gerado agora ficou assim: 49
  • 51. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 9 Note que mais uma vez o Rails assumiu um caminho padrão. Nesse caso, o arquivo é servido diretamente da raiz da aplicação, que é o diretório public. Você pode criar um arquivo chamado default.css no diretório public/stylesheets para adicioná-lo à aplicação. Um exemplo disso seria: Ó Ý ß ÓÒØ¹ Ñ ÐÝ Î Ö Ò ¸ Ö Ð¸ × Ò×¹× Ö ÓÒØ¹× Þ ¼± Uma coisa a manter em mente é que o layout padrão da aplicação não é, de forma alguma, o único que pode ser gerado. Você pode criar tantos layouts quanto precisar, colocando-os no mesmo diretório, de onde estarão acessíveis a toda aplicação. Para usar um layout diferente em um controler você poderia fazer algo assim: Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ð ÝÓÙØ ÓÑ 50
  • 52. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ò Ü Ò Ò O layout cujo nome é home seria especificado no arquivo app/views/layouts/home.rhtml, com a mesma funcionalidade do arquivo application.rhtml. Uma outra possibilidade que o Rails oference é sobrescrever um layout para uma única ação, diretamente no método render. Um exemplo seria: Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ð ÝÓÙØ ÓÑ Ò Ü Ò Ò Ü ×Ô Ð Ö Ò Ö Ø ÓÒ Ð ×Ø ¸ Ð ÝÓÙØ ÓÑ ×Ô Ð Ò Ò Você pode também suprimir inteiramente um layout usando :layout = false. Finalmente, você pode usar maneiras específicas de determinar o layout de uma página. Por exemplo: Ð ×× ÀÓÑ ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ð ÝÓÙØ ÓÓ× Ð ÝÓÙØ Ò Ü Ò ÔÖÓØ Ø ÓÓ× Ð ÝÓÙØ ´ ÙÖÖ ÒØ Ù× Öº Ñ Ò µ Ñ Ò ×ØÖ Ø ÓÒ ÒÓÖÑ Ð Ò Ò No caso acima, dependendo do retorno da chamada ao método admin?, a aplicação poderia usar o layout definido no arquivo administration.rhtml ou no arquivo normal.rhtml. Como podemos ver não há muitos limites para o que pode ser feito. 6.2 Roteamento Se você acessou a URL raiz da aplicação, você terá notado que ela não mudou, apesar do controller que criamos. Isso acontece porque o Rails define um arquivo index.html que serve como padrão. Se removermos esse arquivo do diretório public, ficaremos com a seguinte página: 51
  • 53. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 10 Esse erro indica que o Rails não consegue encontrar um roteamento que satisfaça a URL que especificamos. Para resolvermos o problema, vamos editar o arquivo config/routes.rb, que define esses roteamentos. Esse arquivo contém o seguinte codigo: Ø ÓÒ ÓÒØÖÓÐÐ Ö ÊÓÙØ Ò ÊÓÙØ ׺ Ö Û Ó Ñ Ô Ì ÔÖ ÓÖ ØÝ × × ÙÔÓÒ ÓÖ Ö Ó Ö Ø ÓÒ Öר Ö Ø ¹ ר ÔÖ ÓÖ ØÝº Ë ÑÔÐ Ó Ö ÙÐ Ö ÖÓÙØ Ñ Ôº ÓÒÒ Ø ³ÔÖÓ Ù Ø×» ³¸ ÓÒØÖÓÐÐ Ö ³ Ø ÐÓ ³¸ Ø ÓÒ ³Ú Û³ Ã Ô Ò Ñ Ò ÝÓÙ Ò ×× Ò Ú ÐÙ × ÓØ Ö Ø Ò ÓÒØÖÓÐÐ Ö Ò Ø ÓÒ Ë ÑÔÐ Ó Ò Ñ ÖÓÙØ Ñ ÔºÔÙÖ × ³ÔÖÓ Ù Ø×» »ÔÙÖ × ³¸ ÓÒØÖÓÐÐ Ö ³ Ø ÐÓ ³¸ Ø ÓÒ ³ÔÙÖ × ³ Ì × ÖÓÙØ Ò ÒÚÓ Û Ø ÔÙÖ × ÙÖд ÔÖÓ Ù Øº µ ÓÙ Ò Ú Ø ÖÓÓØ Ó ÝÓÙÖ × Ø ÖÓÙØ Ý ÓÓ Ò ÙÔ ³³ ¹¹ Ùר Ö Ñ Ñ Ö ØÓ Ð Ø ÔÙ Ð » Ò Üº ØÑк Ñ Ôº ÓÒÒ Ø ³³¸ ÓÒØÖÓÐÐ Ö Û Ð ÓÑ ÐÐÓÛ ÓÛÒÐÓ Ò Ï Ë ÖÚ ÏË Ä × Ð Û Ø Ò ÜØ Ò× ÓÒ Òר Ó Ð Ò Ñ ³Û× Ð³ Ñ Ôº ÓÒÒ Ø ³ ÓÒØÖÓÐÐ Ö»× ÖÚ ºÛ× Ð³¸ Ø ÓÒ ³Û× Ð³ 52
  • 54. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÁÒר ÐÐ Ø ÙÐØ ÖÓÙØ × Ø ÐÓÛ ×Ø ÔÖ ÓÖ ØÝº Ñ Ôº ÓÒÒ Ø ³ ÓÒØÖÓÐÐ Ö» Ø ÓÒ» ³ Ò Como os comentários dizem, esse arquivo define roteamentos de URLs para controllers. Cada roteamento é examinado quando uma URL é processada pelo Rails, da primeira para a última, sendo a ordem de declaração a definição de prioridade. Como você pode ver no arquivo acima, a URL padrão que mencionamos, /controller/action/id é a última a ser definida, sendo a aplicada caso não haja instruções em contrário. O roteamento no Rails é bem rico e trabalharemos alguns dos conceitos do mesmo mais adiante. No momento, queremos apenas resolver o problema da página inicial. Essa página é representada no arquivo acima pela linha abaixo, comentada no momento. Ñ Ôº ÓÒÒ Ø ³³¸ ÓÒØÖÓÐÐ Ö Û Ð ÓÑ Para mapear o controller home como nossa página inicial, basta modificar a linha para dizer o seguinte: Ñ Ôº ÓÒÒ Ø ³³¸ ÓÒØÖÓÐÐ Ö ÓÑ A rota vazia é um sinônimo para a rota raiz e estamos dizendo, com o código acima que se a mesma for invocada, a requisição deve ser servida pelo controller que definimos anteriormente. Note a mistura de aspas simples e aspas duplas nesse arquivo. No Ruby, elas são relativa- mente intercambiáveis e são apenas duas das várias formas de representar texto nessa lingua- gem. A diferença é que as aspas duplas permitem a interpolação de variáveis como veremos mais adiante no tutorial. Eu tendo a favorecer o uso de aspas duplas, nas isso é uma opção pessoal. Agora, recarregando nossa página inicial temos: 53
  • 55. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 11 Note que agora o mesmo controller serve dois roteamentos. Essa é apenas uma das possibi- lidades mais simples que estão disponíveis com o roteamento do Rails. Agora que temos um conhecimento básico de models, controllers e views, podemos combinar o três. 54
  • 56. Capítulo 7 Scaffolding e Validações Para ajudar na rápida prototipação de aplicações, o Rails possui algo chamado de scaffolding. E Validações, como o próprio nome indica, são um modo de garantir a integridade dos dados em uma aplicação. 7.1 Scaffolding O scaffolding provê uma estrutura básica para operações CRUD (Create, Retrieve, Update and Delete), ou seja, aquelas operações básicas que temos na manipulação de dados, gerando interfaces rápidas que podem apoiar o desenvolvimento até que você insira a codificação neces- sária. Para experimentar com isso e expandir um pouco nossa aplicação, vamos criar um novo controller, que servirá para administrar os nossos contextos: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» Ò Ö Ø ÓÒØÖÓÐÐ Ö ÓÒØ ÜØ× Ü ×Ø× ÔÔ» ÓÒØÖÓÐÐ Ö×» Ü ×Ø× ÔÔ» ÐÔ Ö×» Ö Ø ÔÔ»Ú Û×» ÓÒØ ÜØ× Ü ×Ø× Ø ×Ø» ÙÒ Ø ÓÒ Ð» Ö Ø ÔÔ» ÓÒØÖÓÐÐ Ö×» ÓÒØ ÜØ× ÓÒØÖÓÐÐ ÖºÖ Ö Ø Ø ×Ø» ÙÒ Ø ÓÒ Ð» ÓÒØ ÜØ× ÓÒØÖÓÐÐ Ö Ø ×ØºÖ Ö Ø ÔÔ» ÐÔ Ö×» ÓÒØ ÜØ× ÐÔ ÖºÖ Inicialmente, esse controller é como o que criamos anteriormente, para a home da aplicação, e não possui nenhuma ação pré-definida. Vamos editar o seu arquivo, em app/controllers/contexts_controller.rb, acrescentando uma linha de código: Ð ×× ÓÒØ ÜØ× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö × ÓÐ ÓÒØ ÜØ Ò Agora, acesse a URL desse controller, digitando http://localhost:3000/contexts no navega- dor que você estiver usando: 55
  • 57. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 12 Sem nenhuma linha de código além da inserida acima, temos listagem, inserção, atualização e remoção de contextos. Clique em New context para experimentar: 56
  • 58. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 13 Depois, clicando em Create, temos: 57
  • 59. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 14 E, finalmente, clicando em Show, vemos: 58
  • 60. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 15 Note, que na tela acima, o id do objeto já aparece na URL. Nesse caso é 5 porque eu já experimentara antes com outros objetos. O scaffolding é muito útil na geração de controllers básicos de administração para dar apoio à prototipação e ao início do desenvolvimento, principalmente para cadastros, permitindo que o desenvolvedor se foque no que é mais importante para a aplicação. O inconveniente é que as ações geradas são bem limitadas e não podem ser editadas ou traduzidas. Para expandir um pouco a funcionalidade, existe outra forma de geração de scaffolding que permite uma flexibilidade maior na edição das páginas geradas, que podem, inclusive, ser utiliza- das como base para as páginas finais. Para isso, use o comando abaixo: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» Ò Ö Ø × ÓÐ ÓÒØ ÜØ Ü ×Ø× ÔÔ» ÓÒØÖÓÐÐ Ö×» Ü ×Ø× ÔÔ» ÐÔ Ö×» Ü ×Ø× ÔÔ»Ú Û×» ÓÒØ ÜØ× Ü ×Ø× Ø ×Ø» ÙÒ Ø ÓÒ Ð» Ô Ò Ò Ý ÑÓ Ð Ü ×Ø× ÔÔ»ÑÓ Ð×» 59
  • 61. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ü ×Ø× Ø ×Ø»ÙÒ Ø» Ü ×Ø× Ø ×Ø» ÜØÙÖ ×» ÒØ Ð ÔÔ»ÑÓ Ð×» ÓÒØ ÜØºÖ ÒØ Ð Ø ×Ø»ÙÒ Ø» ÓÒØ ÜØ Ø ×ØºÖ ÒØ Ð Ø ×Ø» ÜØÙÖ ×» ÓÒØ ÜØ×ºÝÑÐ Ö Ø ÔÔ»Ú Û×» ÓÒØ ܨ׻ ÓÖÑºÖ ØÑÐ Ö Ø ÔÔ»Ú Û×» ÓÒØ ÜØ×»Ð ×ØºÖ ØÑÐ Ö Ø ÔÔ»Ú Û×» ÓÒØ ÜØ×»× ÓÛºÖ ØÑÐ Ö Ø ÔÔ»Ú Û×» ÓÒØ ÜØ×»Ò ÛºÖ ØÑÐ Ö Ø ÔÔ»Ú Û×» ÓÒØ ܨ׻ ØºÖ ØÑÐ ÓÚ ÖÛÖ Ø ÔÔ» ÓÒØÖÓÐÐ Ö×» ÓÒØ ÜØ× ÓÒØÖÓÐÐ ÖºÖ Ò Õ℄ Ý ÓÖ ÔÔ» ÓÒØÖÓÐÐ Ö×» ÓÒØ ÜØ× ÓÒØÖÓÐÐ ÖºÖ ÓÚ ÖÛÖ Ø Ø ×Ø» ÙÒ Ø ÓÒ Ð» ÓÒØ ÜØ× ÓÒØÖÓÐÐ Ö Ø ×ØºÖ Ò Õ℄ Ý ÓÖ Ø ×Ø» ÙÒ Ø ÓÒ Ð» ÓÒØ ÜØ× ÓÒØÖÓÐÐ Ö Ø ×ØºÖ ÒØ Ð ÔÔ» ÐÔ Ö×» ÓÒØ ÜØ× ÐÔ ÖºÖ Ö Ø ÔÔ»Ú Û׻РÝÓÙØ×» ÓÒØ ÜØ×ºÖ ØÑÐ Ö Ø ÔÙ Ð »×ØÝÐ × Ø×»× ÓÐ º ×× Note que, para a geração de um scaffold por esse comando, o nome do modelo de dados é que deve ser passado como parâmetro, e não o nome do controller. O Rails é capaz de derivar um do outro. Esse comando gera a classe do modelo de dados, o controller e views para cada ação CRUD necessária. No caso acima, como o model já existia, ele não foi criado, e foi necessário sobres- crever alguns arquivos. Há duas coisas a serem notadas aqui. Primeiro, o scaffold gerou o seu próprio layout, com sua própria stylesheet. Por causa disso, o layout original da aplicação foi perdido. Uma solução aqui será remover o arquivo app/views/layouts/contexts.rhtml, já que não precisamos dele, e adicionar a stylesheet scaffold.css ao arquivo application.rhtml. Segundo, as views criadas continuam razoavelmente limitadas, como veremos adiante. Abrindo o novo arquivo gerado do controller, temos o seguinte: Ð ×× ÓÒØ ÜØ× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø Ö Ò Ö Ø ÓÒ ³Ð ר³ Ò Ì× × ÓÙÐ × ´× ØØÔ »»ÛÛÛºÛ¿ºÓÖ »¾¼¼½»Ø » Ó »Û ÒÌÓÍ× Øº ØÑе Ú Ö Ý Ñ Ø Ó ÔÓר¸ ÓÒÐÝ ×ØÖÓݸ Ö Ø ¸ ÙÔ Ø ℄¸ Ö Ö Ø ØÓ ß Ø ÓÒ Ð ×Ø Ð ×Ø ÓÒØ ÜØ Ô ×¸ ÓÒØ ÜØ× Ô Ò Ø ÓÒØ ܨ׏ Ô Ö Ô ½¼ Ò × ÓÛ ÓÒØ ÜØ ÓÒØ ÜØº Ò ´Ô Ö Ñ× ℄µ Ò Ò Û ÓÒØ ÜØ ÓÒØ ÜØºÒ Û Ò 60
  • 62. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ö Ø ÓÒØ ÜØ ÓÒØ ÜØºÒ Û´Ô Ö Ñ× ÓÒØ ÜØ℄µ ÓÒØ ÜØº× Ú Ð × ÒÓØ ℄ ³ ÓÒØ ÜØ Û × ×Ù ×× ÙÐÐÝ Ö Ø º³ Ö Ö Ø ØÓ Ø ÓÒ ³Ð ר³ Ð× Ö Ò Ö Ø ÓÒ ³Ò Û³ Ò Ò Ø ÓÒØ ÜØ ÓÒØ ÜØº Ò ´Ô Ö Ñ× ℄µ Ò ÙÔ Ø ÓÒØ ÜØ ÓÒØ ÜØº Ò ´Ô Ö Ñ× ℄µ ÓÒØ ÜØºÙÔ Ø ØØÖ ÙØ ×´Ô Ö Ñ× ÓÒØ ÜØ℄µ Ð × ÒÓØ ℄ ³ ÓÒØ ÜØ Û × ×Ù ×× ÙÐÐÝ ÙÔ Ø º³ Ö Ö Ø ØÓ Ø ÓÒ ³× ÓÛ³¸ ÓÒØ ÜØ Ð× Ö Ò Ö Ø ÓÒ ³ س Ò Ò ×ØÖÓÝ ÓÒØ ÜØº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ Ö Ö Ø ØÓ Ø ÓÒ ³Ð ר³ Ò Ò O resultado final, ao ser executado, é muito parecido com o do método scaffold, com a maior diferença sendo os arquivos de gerados enquanto que, do modo anterior, as ações eram dinami- camente criadas pelo Rails. Algumas amenidades, como paginação, também foram introduzidas. Uma consideração deve ser feita aqui: o scaffolding é apenas um apoio à prototipação. Ele não deve ser usado como uma muleta, gerando páginas para modificação. Se você quer adminis- trações prontas, existem plugins para o Rails que permitem a geração de páginas bem avançadas. Esses plugins podem ser utilizados para criar administrações prontas a exemplo das geradas pelo Django (o framework equivalente ao Rails para o Python), mas mesmo elas tem suas limitações e inflexibilidades. A lição é sempre procurar o que é melhor para a sua aplicação. Os scaffoldings são uma visão muito linear de uma aplicação e não levam em contra interfaces alternativas de melhor usabilidade. De qualquer forma, o scaffolding gerado é uma boa oportunidade para ver o relacionamento entre controllers, views e models. Se você tomar uma ação qualquer como exemplo, verá que ela usa a classe de dados para o acesso ao banco e empacota os dados recebidos em variáveis fechadas que serão usadas por uma view, evitando que o código de apresentação se misture com a lógica de negócio. Mesmo elementos do próprio controller, como paginação, são incluidos nessa discriminação. Veja a view de listagem, por exemplo, descrita no arquivo list.rhtml no diretório app/views/contexts: ½ Ä ×Ø Ò ÓÒØ ÜØ× » ½ Ø Ð ØÖ 61
  • 63. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ± ÓÖ ÓÐÙÑÒ Ò ÓÒØ ÜØº ÓÒØ ÒØ ÓÐÙÑÒ× ± Ø ± ÓÐÙÑÒº ÙÑ Ò Ò Ñ ± »Ø ± Ò ± »ØÖ ± ÓÖ ÓÒØ ÜØ Ò ÓÒØ ÜØ× ± ØÖ ± ÓÖ ÓÐÙÑÒ Ò ÓÒØ ÜØº ÓÒØ ÒØ ÓÐÙÑÒ× ± Ø ± ÓÒØ ÜØº× Ò ´ ÓÐÙÑÒºÒ Ñ µ ± »Ø ± Ò ± Ø ± Ð Ò ØÓ ³Ë ÓÛ³¸ Ø ÓÒ ³× ÓÛ³¸ ÓÒØ ÜØ ± »Ø Ø ± Ð Ò ØÓ ³ س¸ Ø ÓÒ ³ س¸ ÓÒØ ÜØ ± »Ø Ø ± Ð Ò ØÓ ³ רÖÓݳ¸ ß Ø ÓÒ ³ רÖÓݳ¸ ÓÒØ ÜØ ¸ ÓÒ ÖÑ ³ Ö ÝÓ ÔÓר ØÖÙ ± »Ø »ØÖ ± Ò ± »Ø Ð ± Ð Ò ØÓ ³ÈÖ Ú ÓÙ× Ô ³¸ ß Ô ÓÒØ ÜØ Ô ×º ÙÖÖ ÒØºÔÖ Ú ÓÙ× ÓÒØ ÜØ Ô ×º ÙÖÖ ÒØºÔÖ Ú ÓÙ× ± ± Ð Ò ØÓ ³Æ ÜØ Ô ³¸ ß Ô ÓÒØ ÜØ Ô ×º ÙÖÖ ÒØºÒ ÜØ ÓÒØ ÜØ Ô ×º ÙÖÖ ÒØº Ö » ± Ð Ò ØÓ ³Æ Û ÓÒØ ÜØ³¸ Ø ÓÒ ³Ò Û³ ± O método paginate, usado no controller esconde a complexidade de acesso ao banco fazendo a busca dos dados, dividindo os itens retornados pelo número de itens requeridos por página e retornando duas variáveis que contém, respectivamente, uma lista das páginas (que pode ser usada na view para gerar a numeração das mesmas) e os itens referentes àquela página. Se você cadastrar mais de 10 itens, verá isso em funcionamento, embora o scaffold gerado se limite à navegação para frente e para trás na lista de páginas. A view acima também exibe uma complexidade maior, utilizando vários métodos para a ge- ração do seu conteúdo. Notadamente, o método link_to que recebe como o texto do link e pa- râmetros adicionais para a geração da URL, que podem ser combinados de várias formas. Por exemplo: ± Ð Ò ØÓ ÓÒØÖÓÐÐ Ö ÓÑ ± ± Ð Ò ØÓ ÓÒØÖÓÐÐ Ö ÓÒØ ÜØ× ¸ Ø ÓÒ Ø ¸ ¾ ± ± Ð Ò ØÓ ÓÒØÖÓÐÐ Ö ÐÓ Ò ¸ Ù× Ò ÓÓ × ± No primeiro caso acima, o método gera a URL raiz para um controller, que como vimos é mapeada para a ação index. No segundo caso, uma URL completa é retornada. E no terceiro, um parâmetro using é adicionado à requisição, gerando a seguinte URL: /login?using=cookies. O método link_to possui várias outras capacidades entre as quais gerar confirmações em JavaScript e criar forms para submissão confiável de links que modificam destrutivamente seus dados, como pode ser visto nos próprios arquivos geados nesse scaffold. Uma olhada na do- cumentação é recomendada para um esclarecimento maior dessas opções. Um outro conceito interessante apresentado nesse scaffold é o de partials (parciais), que são fragmentos de pági- nas que podem ser compartilhados entre views, da mesma forma que um layout pode usar várias views. Veja, por exemplo, a relação entre os dois arquivos abaixo: Primeiro, a view para criação de um novo registro: 62
  • 64. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ½ Æ Û ÓÒØ ÜØ » ½ ± ר ÖØ ÓÖÑ Ø Ø ÓÒ ³ Ö Ø ³ ± ± Ö Ò Ö Ô ÖØ Ð ³ ÓÖѳ ± ± ×Ù Ñ Ø Ø Ö Ø ± ± Ò ÓÖÑ Ø ± ± Ð Ò ØÓ ³ ³¸ Ø ÓÒ ³Ð ר³ ± Agora, a view para edição de um registro: ½ Ø Ò ÓÒØ ÜØ » ½ ± ר ÖØ ÓÖÑ Ø Ø ÓÒ ³ÙÔ Ø ³¸ ÓÒØ ÜØ ± ± Ö Ò Ö Ô ÖØ Ð ³ ÓÖѳ ± ± ×Ù Ñ Ø Ø ³ س ± ± Ò ÓÖÑ Ø ± ± Ð Ò ØÓ ³Ë ÓÛ³¸ Ø ÓÒ ³× ÓÛ³¸ ÓÒØ ÜØ ± ± Ð Ò ØÓ ³ ³¸ Ø ÓÒ ³Ð ר³ ± Note que o código gerado é muito parecido (de fato os dois arquivos e suas ações relaciona- das poderiam ser combinados em um único ponto de acesso) e em ambos os arquivos há uma chamada ao método render, usando um partial. Esse partial se encontra no arquivo _form.rhtml, no mesmo diretório. Arquivos que definem partials sempre começam com _ para especificar que são fragmentos. O conteúdo do arquivo é simples: ± ÖÖÓÖ Ñ ×× × ÓÖ ³ ÓÒØ ÜØ³ ± ¹¹ ÓÖÑ ÓÒØ ÜØ℄¹¹ Ô Ð Ð ÓÖ ÓÒØ ÜØ Ò Ñ Æ Ñ »Ð Ð Ö» ± Ø ÜØ Ð ³ ÓÒØ ÜØ³¸ ³Ò Ñ ³ ± »Ô ¹¹ Ó ÓÖÑ ÓÒØ ÜØ℄¹¹ Nesse caso, a parte do formulário que é comum tanta à inserção de um contexto quanto à sua edição. Partials são uma das grandes facilidades do Rails, sendo utilizados principalmente em aplica- ções Ajax para gerar somente os fragmentos do código necessários para atualizações de partes de uma página. Hoje, com o uso do templates RJS, eles se tornaram ainda mais importantes. Se você utilizar o scaffold gerado, verá que o código é um pouco mais polido, com mensagens de sucesso e paginação, mas com pouco diferença do que poderia ser feito com uma única linha de código, como visto anteriormente. Por isso, a observação anterior de que scaffolds são utéis, mas não devem se tornar uma regra na aplicação. Um grande exemplo das limitações é o modo como os scaffolds básicos do Rails geram as tabelas de listagens, fazendo invocações diretas aos atributos de um objeto em um loop com pouca possibilidade de customização. Veja o fragmento de código abaixo, proveniente da view index.rhtml: ØÖ ± ÓÖ ÓÐÙÑÒ Ò ÓÒØ ÜØº ÓÒØ ÒØ ÓÐÙÑÒ× ± Ø ± ÓÐÙÑÒº ÙÑ Ò Ò Ñ ± »Ø ± Ò ± »ØÖ 63
  • 65. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Os cabeçalhos da tabela de listagem são gerados fazendo uma iteração sobre as colunas de conteúdo do modelo de dados em questão, que não incluem colunas avançadas de relacio- namento e nem são capazes de fazer a tradução adequada de colunas que contenham valores booleanos, enumerados e tipos de dados próprios do banco. Além disso, o método human_name é voltado para o idioma inglês e embora exista a possibilidade de adaptá-lo para outro idioma por meio de plugins e outros métodos, as limitações dessas técnicas são logo aparentes e, se cuidado não for tomado, podem levar a problemas de lógica na aplicação, tornando a mesma desnecessariamente complexa e violando os princípios básicos de simplicidade sobre os quais o Rails foi construído. Aproveitando momentaneamente o código gerado, vamos avançar um pouco em nossa apli- cação, fazendo uso de mais uma característica no Rails. 7.2 Validações O modelo de validações que o Rails fornece é bastante completo e pode ser facilmente ex- pandido pelo desenvolvedor caso ele necessite de algo não fornecido por padrão nas bibliotecas. No caso da nossa classe de dados inicial, precisamos validar pelo menos o fato do usuário ter informado o nome do contexto ao cadastrá-lo. Para isso, vamos abrir o arquivo da classe, que está em app/models/context.rb, e editá-lo, inserindo uma validação simples: Ð ×× ÓÒØ ÜØ Ø Ú Ê ÓÖ × Ú Ð Ø × ÔÖ × Ò Ó Ò Ñ Ò Se você tentar inserir agora um contexto sem nome, verá o seguinte: 64
  • 66. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 16 A menos que o usuário informe o nome do contexto, o Rails não permitirá que o objeto seja salvo. Note que a validação é feita no modelo de dados e refletida na view através dos métodos da mesma. O método error_messages_for recolhe todas as mensagens de erro geradas durante uma va- lidação e gera o HTML necessário para exibi-las, que, no caso acima, ainda é formatado pela stylesheet scaffold.css criada anteriormente. Da mesma forma, os métodos responsáveis pela geração dos itens de formulário (como text_field, text_area, select e datetime_select, entre ou- tros) são capazes de verificar se o campo a que se referem não falhou em alguma validação e encapsular a exibição do campo em uma indicação de erro. Múltiplas validações podem ser efetuadas em um mesmo campo. Por exemplo, para prevenir a inserção de nomes duplicados, a seguinte condição poderia ser colocada na classe: Ð ×× ÓÒØ ÜØ Ø Ú Ê ÓÖ × Ú Ð Ø × ÔÖ × Ò Ó Ò Ñ Ú Ð Ø × ÙÒ ÕÙ Ò ×× Ó Ò Ñ Ò O resultado seria: 65
  • 67. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 17 As mensagens de erro geradas são padronizadas no próprio Rails, mas podem ser customi- zadas usando o seguinte formato: Ð ×× ÓÒØ ÜØ Ø Ú Ê ÓÖ × Ú Ð Ø × ÔÖ × Ò Ó Ò Ñ Ú Ð Ø × ÙÒ ÕÙ Ò ×× Ó Ò Ñ ¸ Ñ ×× ÑÙר ÙÒ ÕÙ Ò Note que o método error_messages_for é voltado para o inglês, formando frases que fazem mais sentido nesse idioma, enquanto o nosso português prefere frases mais elaboradas. É facil substituir o método acima por uma implementação mais interessante do mesmo que atenda ao português e como veremos mais adiante, em outra seção do tutorial. Um último passo seria atualizar esse scaffold para usar o layout que criamos. Para isso, re- mova o arquivo contexts.rhtml e atualize o arquivo application.rhtml (ambos no diretório app/views/layouts) para o seguinte: ØÑÐ Ø ØÐ Ì »Ø ØÐ 66
  • 68. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ± רÝÐ × Ø Ð Ò Ø ÙÐØ ± ± רÝÐ × Ø Ð Ò Ø × ÓÐ ± » Ó Ý ± Ý Ð ± » Ó Ý » ØÑÐ A mudança não é grande, mas significa que nosso scaffold agora usa o layout da aplicação, recebendo todas as modificações provenientes do mesmo. Cabe uma nota aqui sobre as ações geradas no scaffold e, por extensão, qualquer outra ação a ser criada em uma aplicação. Um movimento dentro da comunidade do Rails hoje é o uso de métodos REST, que representam uma interpretação de um conjunto de padrões e filosofias de desenvolvimento Web. Esses métodos usam verbos HTTP mais específicos como PUT e DELETE para efetuar suas ações, ao invés de usar somente os usuais GET e POST. A próxima versão do Rails, ao que tudo indica, virá com um suporte bem forte para esse tipo de uso. O presente tutorial não entrará nesses detalhes sobre isso, mas deixo ao leitor alguns recursos para que ele possa pesquisar mais sobre o assunto: ØØÔ »»ÛÛÛºÜÑк ÓÑ»ÔÙ » »¾¼¼ »½½»¼¾»Ö ר¹ÓÒ¹Ö Ð׺ ØÑÐ ØØÔ »»Ô ÞÖ º Ö ÐÝ ÒÓÙ ºÓÖ » ÐÓ »¾¼¼ »¼¿» ÒÓØ Ö¹Ö ×Ø¹ ÓÒØÖÓÐÐ Ö¹ ÓÖ¹Ö Ð×» ØØÔ »»ÛÛÛº Ð Û Ú ÐÓÔÑ ÒØº ÓÑ»ÔÐÙ Ò×»× ÑÔÐÝÖ ×Ø ÙÐ Agora que vimos com o básico funciona no Rails, podemos partir para tentar a nossa própria implementação, aprendendo mais sobre com as coisas funcionam. 67
  • 69. Capítulo 8 Segundo Controller Nessa lição, vamos criar o cadastro de projeto, que também é bem simples, de forma mais manual para entendermos como uma aplicação comum processa seus dados. Para facilitar, vamos combinar a criação e edição de um registro em uma única ação. 8.1 Início O primeiro passo é atualizar o modelo de dados para efetuar validações. No caso no nosso modelo de dados para projetos (que está no arquivo app/models/project.rb), precisamos de va- lidações igualmente simples. A classe ficaria, assumindo que o atributo description é opcional, assim: Ð ×× ÈÖÓ Ø Ø Ú Ê ÓÖ × Ú Ð Ø × ÔÖ × Ò Ó Ò Ñ Ú Ð Ø × ÙÒ ÕÙ Ò ×× Ó Ò Ñ Ò Um segundo passo é gerar um controller para lidar com as requisições relacionadas ao ca- dastro de projetos. Dessa vez, vamos usar o comando de geração do controllers especificando já as ações que desejamos criar automaticamente. Basicamente, queremos as ações index, list, edit e delete. A ação index existe para não precisarmos de uma regra de roteamento explícita mas será meramente uma invocação da ação list. E ação edit resumirá todas as ações de criação e inserção, simplicando o código. O comando para gerar controller é o seguinte: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» Ò Ö Ø ÓÒØÖÓÐÐ Ö ÔÖÓ Ø× Ò Ü Ð ×Ø Ø Ð Ø Ü ×Ø× ÔÔ» ÓÒØÖÓÐÐ Ö×» Ü ×Ø× ÔÔ» ÐÔ Ö×» Ö Ø ÔÔ»Ú Û×»ÔÖÓ Ø× Ü ×Ø× Ø ×Ø» ÙÒ Ø ÓÒ Ð» Ö Ø ÔÔ» ÓÒØÖÓÐÐ Ö×»ÔÖÓ Ø× ÓÒØÖÓÐÐ ÖºÖ Ö Ø Ø ×Ø» ÙÒ Ø ÓÒ Ð»ÔÖÓ Ø× ÓÒØÖÓÐÐ Ö Ø ×ØºÖ Ö Ø ÔÔ» ÐÔ Ö×»ÔÖÓ Ø× ÐÔ ÖºÖ Ö Ø ÔÔ»Ú Û×»ÔÖÓ Ø×» Ò ÜºÖ ØÑÐ Ö Ø ÔÔ»Ú Û×»ÔÖÓ Ø×»Ð רºÖ ØÑÐ Ö Ø ÔÔ»Ú Û×»ÔÖÓ Ø×» ØºÖ ØÑÐ Ö Ø ÔÔ»Ú Û×»ÔÖÓ Ø×» Ð Ø ºÖ ØÑÐ 68
  • 70. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Como você pode ver, os arquivos das views foram automaticamente criados, e se você abrir o arquivo do controller em si (app/controllers/projects_controller.rb) você verá o esqueleto que foi gerado: Ð ×× ÈÖÓ Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ò Ð ×Ø Ò Ø Ò Ð Ø Ò Ò Invocando o controller em seu navegador, você verá o seguinte: Figura 18 Nós agora temos um controller que responde perfeitamente às nossas ações, com views já associadas, prontas para o uso. 69
  • 71. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Como a ação index é somente uma invocação da ação list, podemos remover o arquivo da view da mesma que está em app/views/projects/index.rhtml e começar a editar as ações. O método index é muito simples: Ð ×× ÈÖÓ Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø Ò Ø Ò Ð Ø Ò Ò O que essas duas linhas nos dizem são: primeiro, invoque o método list, e depois renderize a view da ação list. Mesmo representando uma ação em si, list não passa de um método comum da classe. É somente a mágica do Rails que o torna uma ação, e, sendo assim, ele pode ser invocado normalmente, como qualquer outra método. A segunda linha é necessária porque o mecanismo automático de identificação de views procuraria a view relacionada a index e não a list. Precisamos, então, explicitar a que será usada pela aplicação. Antes de construirmos a ação list, precisamos providenciar um modo de inserirmos registros do banco. Para isso, precisamos criar a nossa ação edit. Temos duas situações possíveis: ou o usuário está criando um novo registro, ou ele está atualizando um registro existente. Obviamente, a única diferença entre esses dois métodos é a existência ou não do objeto. E a primeira coisa a ser feita tanto na criação quanto na edição de um objeto é exibir o formulário do mesmo para preenchimento. Como ações relacionadas somente a exibição geralmente são associadas ao método HTTP GET enquanto ações que modificam dados e dependem de formulários são invocadas a partir do método POST, vamos usar essa diferenciação para identificar se estamos salvando o objeto ou somente exibindo o formulário para edição. E mais, vamos usar a existência ou não do parâmetro id para identificar se estamos lidando com um novo objeto ou com um objeto já existente. A primeira versão do nosso método ficaria assim, então: Ð ×× ÈÖÓ Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø Ò Ø Ô Ö Ñ× ℄ ÔÖÓ Ø ÈÖÓ Øº Ò ´Ô Ö Ñ× ℄µ Ð× ÔÖÓ Ø ÈÖÓ ØºÒ Û Ò 70
  • 72. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ö ÕÙ ×ØºÔÓר Ò Ò Ð Ø Ò Ò O segundo teste do método verifica se estamos recebendo uma requisição POST. Como men- cionamos anteriormente, é isso que vamos usar para saber se estamos simplesmente exibindo o formulário (seja vazio ou não), ou se está na hora de persistir o objeto para o banco. Mais à frente colocaremos esse código. Caso você ache que o nome edit para esse método é meio enganoso quando um novo re- gistro está sendo criado, você pode usar regras de roteamento genéricas para especificar que invocações a ações chamadas create, update, e save são redirecionadas para a mesma ação edit. Separar ou não as suas ações é um decisão que depende obviamente do que você está fazendo no momento. A tendência com o uso de REST, inclusive, é de ações bem específicas, que respondem a somente um tipo de verbo HTTP. Agora que o nosso método começou a tomar forma, precisamos editar a view edit.html para exibir o nosso formulário. O arquivo presente está assim: ½ ÈÖÓ Ø× Ø » ½ Ô Ò Ñ Ò ÔÔ»Ú Û×»ÔÖÓ Ø×» ØºÖ ØÑÐ »Ô Precisamos indicar ao usuário se estamos editando um registro existente ou adicionando um novo registro no próprio cabeçalho da página. Para isso podemos usar o seguinte código: ½ ± ÔÖÓ ØºÒ Û Ö ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ Ø » ½ Note que estamos usando a variável @project que criamos no método edit. O @ indica uma variável de instância, que o Rails automaticamente propaga para qualquer view sendo processada a partir da ação em que a variável foi definida. Na linha acima, estamos usando o método new_record?, presente em todas as classes de dados derivadas do ActiveRecord para identificar se estamos lidando com um novo registro ou com um registro já existente. Esse método retorna verdadeiro enquanto a classe não for salva pela primeira vez. Com base nisso, exibimos o nosso cabeçalho. Se você rodar a página, invocando diretamente a URL /projects/edit, verá que já temos algo funcionando: 71
  • 73. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 19 Obviamente, se você tentar usar um id qualquer você verá um erro a menos que tenha inserido aquele registro no banco de dados. O próximo passo agora é criar o formulário de dados. Para isso, vamos editar a nossa view: ½ ± ÔÖÓ ØºÒ Û Ö ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ Ø » ½ ± ר ÖØ ÓÖÑ Ø Ø ÓÒ Ø ¸ ÔÖÓ Ø ± ± Ò ÓÖÑ Ø ± O método start_form_tag funciona de maneira muito similar o método link_to, explicado anterior- mente. No caso acima, estamos gerado um formulário apontando para a ação edit e passando o id do objeto que estamos usando, seja novo ou não. Duas coisas são interessantes nesse chamada: primeiro, o Rails é inteligente o bastante para perceber que você está passando o objeto como se fosse o seu id e gerar o código necessário au- tomaticamente; segundo, caso o objeto não tenha sido salvo, o Rails suprimirá automaticamente o id sem que você precise fazer qualquer teste. O outro método chamado, end_form_tag, simplesmente gera o fechamento do elemento form na página. Com o cabeçalho do nosso formulário gerado, podemos agora criar campos para edição. Um projeto possui um nome e um descrição. O primeiro atributo é um texto simples, de uma linha 72
  • 74. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF somente, enquanto o segundo é um texto que pode ter múltiplas linhas. Editando o nosso arquivo, teremos o seguinte: ½ ± ÔÖÓ ØºÒ Û Ö ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ Ø » ½ ± ר ÖØ ÓÖÑ Ø Ø ÓÒ Ø ¸ ÔÖÓ Ø ± Ô Ð Ð ÓÖ ÔÖÓ Ø Ò Ñ Æ Ñ »Ð Ð Ö ± Ø ÜØ Ð ÔÖÓ Ø ¸ Ò Ñ ± »Ô Ô Ð Ð ÓÖ ÔÖÓ Ø × Ö ÔØ ÓÒ × Ö ÔØ ÓÒ »Ð Ð Ö ± Ø ÜØ Ö ÔÖÓ Ø ¸ × Ö ÔØ ÓÒ ¸ ÖÓÛ× ± »Ô ± Ò ÓÖÑ Ø ± Essa modificação nos dá o seguinte: Figura 20 73
  • 75. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Os métodos text_field e text_area são responsáveis pela geração dos elementos de formu- lário vistos acima. O Rails possui dezenas desses métodos, capazes de gerar várias combina- ções possíveis para os tipos de dados suportados automaticamente e permitir extensões se você precisar de algo mais customizado. E você sempre pode gerar o seu código manualmente em situações especiais. Veja que cada método recebe um objeto e um atributo a ser gerado. No caso desses métodos, você não precisa usar o @ diretamente: basta passar o nome do objeto e o método saberá recuperá-lo do controller que está sendo executado. Se você olhar o HTML gerado, verá o seguinte: Ô Ð Ð ÓÖ ÔÖÓ Ø Ò Ñ Æ Ñ »Ð Ð Ö ÒÔÙØ ÔÖÓ Ø Ò Ñ Ò Ñ ÔÖÓ Ø Ò Ñ ℄ × Þ ¿¼ ØÝÔ Ø ÜØ » »Ô Ô Ð Ð ÓÖ ÔÖÓ Ø × Ö ÔØ ÓÒ × Ö ÔØ ÓÒ »Ð Ð Ö Ø ÜØ Ö ÓÐ× ¼ ÔÖÓ Ø × Ö ÔØ ÓÒ Ò Ñ ÔÖÓ Ø × Ö ÔØ ÓÒ℄ ÖÓÛ× »Ø ÜØ Ö »Ô Veja que os métodos geram um formato similar de elementos, criando atributos name e id específicos para facilitar a vida do desenvolvedor. O atributo id pode ser associado a um elemento label como demonstrado e o atributo name é o que é enviado ao Rails, gerando automaticamente uma tabela hash dos dados submetidos pelo formulário que a ação pode usar. Dentro de um controller você será capaz de usar params[:project] para acessar diretamente essa tabela hash, como você verá adiante. O próximo passo, agora, é adicionar ações para salvar ou cancelar a edição. Poderíamos ter algo assim: ½ ± ÔÖÓ ØºÒ Û Ö ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ Ø » ½ ± ר ÖØ ÓÖÑ Ø Ø ÓÒ Ø ¸ ÔÖÓ Ø ± Ô Ð Ð ÓÖ ÔÖÓ Ø Ò Ñ Æ Ñ »Ð Ð Ö ± Ø ÜØ Ð ÔÖÓ Ø ¸ Ò Ñ ± »Ô Ô Ð Ð ÓÖ ÔÖÓ Ø × Ö ÔØ ÓÒ × Ö ÔØ ÓÒ »Ð Ð Ö ± Ø ÜØ Ö ÔÖÓ Ø ¸ × Ö ÔØ ÓÒ ¸ ÖÓÛ× ± »Ô Ô ± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò Ð ¸ Ø ÓÒ Ð ×Ø ± »Ô ± Ò ÓÖÑ Ø ± O formato acima é uma preferência de muitas aplicações Rails e reflete o fato de que a ação para salvar deveria ser submetida pelo formulário enquanto a ação de cancelamento seria sim- plesmente um retorno a um estado anterior. Mais do que isso, o método acima evita que tenha- mos que descobrir qual botão foi pressionado em nosso formulário. Embora o código para isso seja bem simples, repetí-lo em cada formulário se tornaria rapidamente tedioso, além de forçar uma mistura de apresentação com lógica que queremos evitar a todo custo. 74
  • 76. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Esse é um padrão que você verá repetidamente em aplicações atuais e que faz bastante sentido do ponto de vista de usabilidade. O resultado seria: Figura 21 Temos agora um formulário completo funcionando. Precisamos simplesmente salvar o que será submetido. Voltando ao nosso controller, ficamos com o seguinte: Ð ×× ÈÖÓ Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø Ò Ø Ô Ö Ñ× ℄ ÔÖÓ Ø ÈÖÓ Øº Ò ´Ô Ö Ñ× ℄µ 75
  • 77. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ð× ÔÖÓ Ø ÈÖÓ ØºÒ Û Ò Ö ÕÙ ×ØºÔÓר ÔÖÓ Øº ØØÖ ÙØ × Ô Ö Ñ× ÔÖÓ Ø℄ ÔÖÓ Øº× Ú Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Ò Ð Ø Ò Ò Todo objeto que representa uma classe de dados no Rails possui um atributo chamado at- tributes, que representa uma coleção das colunas da tabela equivalentes. Esse atributo aceita receber uma tabela hash para preenchimento de seus valores. Como mencionado anteriormente, é aqui que os dados gerados pelo Rails na submissão do formulário vem a calhar, servindo para associação direta no objeto. Cada item existente em params[:project] no código acima, como, por exemplo, params[:project][:name], preencherá seu item correspondente sem necessidade de código adicional. Continuando o código, tentamos salvar o objeto. Se isso tem sucesso (ou seja, se nenhuma validação falha) redirecionamos para a página de listagem. Caso contrário, exibimos o formulá- rio novamente. Nesse caso, note que o Rails usará a mesma view, seguindo o comportamento padrão, efetivamente mostrando o formulário preenchido com os dados postados. Isso acontece porque os métodos text_field e text_area (e os demais) preenchem automaticamente os elemen- tos de formulário com os valores existentes no objeto que receberam. Isso torna a nossa tarefa bem simples. Se você tentar salvar um formulário sem preencher nada, verá o seguinte agora: 76
  • 78. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 22 Notamos que a validação está funcionando, mas nenhum erro é exibido. Para isso, precisamos da seguinte modificação em nossa view: ½ ± ÔÖÓ ØºÒ Û Ö ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ Ø » ½ ± ÖÖÓÖ Ñ ×× × ÓÖ ÔÖÓ Ø ± ± ר ÖØ ÓÖÑ Ø Ø ÓÒ Ø ¸ ÔÖÓ Ø ± Ô Ð Ð ÓÖ ÔÖÓ Ø Ò Ñ Æ Ñ »Ð Ð Ö ± Ø ÜØ Ð ÔÖÓ Ø ¸ Ò Ñ ± »Ô Ô Ð Ð ÓÖ ÔÖÓ Ø × Ö ÔØ ÓÒ × Ö ÔØ ÓÒ »Ð Ð Ö ± Ø ÜØ Ö ÔÖÓ Ø ¸ × Ö ÔØ ÓÒ ¸ ÖÓÛ× ± »Ô Ô ± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò Ð ¸ Ø ÓÒ Ð ×Ø ± »Ô ± Ò ÓÖÑ Ø ± 77
  • 79. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF O que nos dá: Figura 23 Se você salvar um objeto agora, verá que somos redirecionados para a ação list que ainda precisamos criar. Uma listagem é algo bem simples e queremos exibir, inicialmente, somente o nome do projeto. Para isto, vamos criar algo bem básico: ½ ÈÖÓ Ø× » ½ Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø Æ Ñ »Ø »ØÖ »Ø Ð Isso nos dá um tabela simples. Agora, queremos exibir os registros criados. Precisamos, obviamente, buscar esses objetos no banco. Modificando o controller ficamos com algo assim: Ð ×× ÈÖÓ Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü 78
  • 80. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ð ×Ø Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø ÔÖÓ Ø× ÈÖÓ Øº Ò Ðи ÓÖ Ö Ò Ñ Ò Ø Ô Ö Ñ× ℄ ÔÖÓ Ø ÈÖÓ Øº Ò ´Ô Ö Ñ× ℄µ Ð× ÔÖÓ Ø ÈÖÓ ØºÒ Û Ò Ö ÕÙ ×ØºÔÓר ÔÖÓ Øº ØØÖ ÙØ × Ô Ö Ñ× ÔÖÓ Ø℄ ÔÖÓ Øº× Ú Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Ò Ð Ø Ò Ò Uma variável chamada @projects receberá uma lista de todos projetos ordenados pelo atri- buto name. O método find, já tratado anteriormente, recebe como primeiro parâmetro uma espe- cificação do que retornar ou um id específico. No caso acima, queremos todos registros (all). O segundo parâmetro, nomeado, recebe a especificação de ordenação. Um detalhe da chamada acima. Muitas vezes, em código Ruby, você verá um seqüência de parâmetros nomeados no fim de uma chamada. O Ruby não possui parâmetros nomeados em si, mas é capaz de simular isso com o uso de uma tabela hash com último parâmetro de um método. Quando um método usa essa técnica, o Ruby automaticamente permite que os parâmetros sejam declarados de forma livre, pelo nome, e os combina no momento da chamada em uma tabela hash que é então passada como parâmetro. Assim, o primeiro parâmetro do método find acima é um símbolo e o segundo parâmetro é uma tabela hash cujo único elemento é um par definido por um símbolo e uma string. Agora, já podemos usar esses objetos em uma view: ½ ÈÖÓ Ø× » ½ Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø Æ Ñ »Ø »ØÖ ± ÔÖÓ Ø×º Ó ÔÖÓ Ø ± Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø ± ÔÖÓ ØºÒ Ñ ± »Ø »ØÖ ± Ò ± »Ø Ð 79
  • 81. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF No caso acima, o método find retorna um array que pode ou não conter itens. Uma coisa a manter em mente aqui é que, para caso de uso desse método, o retorno pode ser diferente. Se você estiver usando find com :first, o retorno será um objeto ou o valor nil. Se você estiver passando um id específico, um objeto será retornado ou um erro será gerado. Lembre-se disso sempre que usar o método em suas variações. As variações servem para cobrir as situa- ções mais comuns, e você sempre pode escrever seus próprios métodos usando as combinações acima para obter o resultado que deseja. Com dois projetos inseridos, o resultado é: Figura 24 Podemos agora modificar a nossa view para permitir algumas ações sobre esses objetos. Por exemplo: ½ ÈÖÓ Ø× » ½ Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø Æ Ñ »Ø Ø Ø ÓÒ× »Ø »ØÖ 80
  • 82. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ± ÔÖÓ Ø×º Ó ÔÖÓ Ø ± ØÖ Ø ± ÔÖÓ ØºÒ Ñ ± »Ø Ø ± Ð Ò ØÓ Ø ¸ Ø ÓÒ Ø ¸ ÔÖÓ Ø ± ÓÖ ± Ð Ò ØÓ Ð Ø ¸ Ø ÓÒ Ð Ø ¸ ÔÖÓ Ø ± »Ø »ØÖ ± Ò ± »Ø Ð Como você dever ter notado pelas chamadas a link_to na view acima e em outros pontos do código já exibido, o Rails é capaz de derivar os elementos da uma URL dos parâmetros que estão sendo usados no momento. O resultado da aplicação da view acima é visto abaixo: Figura 25 Clicando na edição de um dos itens acima, temos: 81
  • 83. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 26 Como é possível ver, o cabeçalho da página mudou para indicar uma edição e os campos já vieram preenchidos. Você já pode alterar cada objeto sem problemas. Precisamos agora de refinar alguns aspectos de nosso controller. Precisamos de um link para criar um novo registro. Isso é facilmente conseguido: ½ ÈÖÓ Ø× » ½ Ô ± Ð Ò ØÓ Æ Û ÈÖÓ Ø ¸ Ø ÓÒ Ø ± »Ô Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø Æ Ñ »Ø Ø Ø ÓÒ× »Ø »ØÖ ± ÔÖÓ Ø×º Ó ÔÖÓ Ø ± ØÖ Ø ± ÔÖÓ ØºÒ Ñ ± »Ø Ø ± Ð Ò ØÓ Ø ¸ Ø ÓÒ Ø ¸ ÔÖÓ Ø ± ÓÖ ± Ð Ò ØÓ Ð Ø ¸ Ø ÓÒ Ð Ø ¸ ÔÖÓ Ø ± 82
  • 84. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF »Ø »ØÖ ± Ò ± »Ø Ð Um dos problemas em deixar que um registro seja removido com um simples invocação é que o usuário não tem como reverter a ação. Podemos adicionar um mínimo de proteção com a seguinte alteração: ½ ÈÖÓ Ø× » ½ Ô ± Ð Ò ØÓ Æ Û ÈÖÓ Ø ¸ Ø ÓÒ Ø ± »Ô Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø Æ Ñ »Ø Ø Ø ÓÒ× »Ø »ØÖ ± ÔÖÓ Ø×º Ó ÔÖÓ Ø ± ØÖ Ø ± ÔÖÓ ØºÒ Ñ ± »Ø Ø ± Ð Ò ØÓ Ø ¸ Ø ÓÒ Ø ¸ ÔÖÓ Ø ± ÓÖ ± Ð Ò ØÓ Ð Ø ¸ ß Ø ÓÒ Ð Ø ¸ ÔÖÓ Ø ¸ ÓÒ ÖÑ Ö ÝÓÙ × »Ø »ØÖ ± Ò ± »Ø Ð Note que, por estamos usando um terceiro parâmetro do método link_to, precisamos de adi- cionar chaves ao redor do segundo para que o Ruby não exerça o seu comportamento padrão e concatene todos os parâmetros livres em um só. No caso acima, tanto o segundo parâmetro da chamada como o terceiro são tabelas hash, embora somente a segunda esteja explicitamente indicada. O resultado das modificações acima é o seguinte, como podemos ver ao clicar na ação para remover o projeto: 83
  • 85. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 27 A ação delete também pode ser protegida de acesso GET diretos com o uso de outra carac- terística do Rails que é a transformação de links em formulários caso a ação seja bem simples. O resultado visual não é muito interessante e você pode observá-lo no código do scaffold que foi gerado anteriormente para o modelo de dados de contextos. Vamos agora inserir a ação para excluir registros, que é bem simples: Ð ×× ÈÖÓ Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø ÔÖÓ Ø× ÈÖÓ Øº Ò Ðи ÓÖ Ö Ò Ñ Ò Ø Ô Ö Ñ× ℄ ÔÖÓ Ø ÈÖÓ Øº Ò ´Ô Ö Ñ× ℄µ Ð× 84
  • 86. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÔÖÓ Ø ÈÖÓ ØºÒ Û Ò Ö ÕÙ ×ØºÔÓר ÔÖÓ Øº ØØÖ ÙØ × Ô Ö Ñ× ÔÖÓ Ø℄ ÔÖÓ Øº× Ú Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Ò Ð Ø ÈÖÓ Øº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Como essa ação não possui nenhuma view, o arquivo gerado delete.rhtml também pode ser excluído. Uma outra alteração que pode ser feita é a exibição de mensagens de dados para algumas ações. Para isso, vamos usar uma outra característica dos Rails, as variáveis flash. Essas variá- veis são similares a variáveis de sessão, mas somente persistem de uma página para outra. Uma vez que a requisição para a qual foram propagadas acaba, elas são automaticamente removidas do contexto de execução. Vamos modificar nosso controller mais uma vez: Ð ×× ÈÖÓ Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø ÔÖÓ Ø× ÈÖÓ Øº Ò Ðи ÓÖ Ö Ò Ñ Ò Ø Ô Ö Ñ× ℄ ÔÖÓ Ø ÈÖÓ Øº Ò ´Ô Ö Ñ× ℄µ Ð× ÔÖÓ Ø ÈÖÓ ØºÒ Û Ò Ö ÕÙ ×ØºÔÓר ÔÖÓ Øº ØØÖ ÙØ × Ô Ö Ñ× ÔÖÓ Ø℄ ÔÖÓ Øº× Ú Ð × ÒÓØ ℄ Ì ÔÖÓ Ø Û × ×Ù ×× ÙÐÐÝ × Ú Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Ò 85
  • 87. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ð Ø ÈÖÓ Øº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ Ð × ÒÓØ ℄ Ì ÔÖÓ Ø Û × ×Ù ×× ÙÐÐÝ Ð Ø Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Podemos agora usar essas variáveis em nossa view para a ação list, que é para onde as duas ações em questão retornam: ½ ÈÖÓ Ø× » ½ ± Ð × ÒÓØ ℄ ± Ô ×ØÝÐ ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð ± Ð × ÒÓØ ℄ ± »Ô ± Ò ± Ô ± Ð Ò ØÓ Æ Û ÈÖÓ Ø ¸ Ø ÓÒ Ø ± »Ô Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø Æ Ñ »Ø Ø Ø ÓÒ× »Ø »ØÖ ± ÔÖÓ Ø×º Ó ÔÖÓ Ø ± ØÖ Ø ± ÔÖÓ ØºÒ Ñ ± »Ø Ø ± Ð Ò ØÓ Ø ¸ Ø ÓÒ Ø ¸ ÔÖÓ Ø ± ÓÖ ± Ð Ò ØÓ Ð Ø ¸ ß Ø ÓÒ Ð Ø ¸ ÔÖÓ Ø ¸ ÓÒ ÖÑ Ö ÝÓÙ ×Ù »Ø »ØÖ ± Ò ± »Ø Ð Uma pequena observação que cabe aqui é o uso de símbolos ao invés de strings na referên- cia a tabelas hash. Símbolos são sempre uma forma de acesso mais interessante por apontarem sempre para uma única instância e poderem ser otimizados pelo interpretador. O Rails geral- mente permite as duas formas de acesso para suas variáveis internas representadas com tabelas hash, mas é sempre bom escolher um dos métodos de acesso e manter um padrão em relação ao mesmo. Isso facilita a legibilidade da aplicação e evita o aparecimento de erros proveniente da mistura dos dois tipos de acesso. O resultado é o seguinte, após uma ação de edição: 86
  • 88. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 28 A variável flash[:notice] está disponível somente naquela requisição como você pode verificar recarregando a página. 87
  • 89. Capítulo 9 Extendendo um modelo de dados e Helpers Essa lição visa extender nosso modelo de dados para aproveitando o nosso controller. E mostrar o que são os Helpers. 9.1 Extendendo um modelo de dados Algo que podemos fazer agora, para aproveitar o nosso controller é extender o nosso modelo de dados. Vamos dizer que precisamos saber se um projeto está ativo ou não. O nosso modelo de dados não contém esse atributo, mas podemos gerar uma migração para isso. ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» Ò Ö Ø Ñ Ö Ø ÓÒ ×Ø ØÙ× ØÓ ÔÖÓ Ø Ü ×Ø× »Ñ Ö Ø Ö Ø »Ñ Ö Ø »¼¼ ר ØÙ× ØÓ ÔÖÓ ØºÖ Essa é uma migração um pouco diferente porque adiciona uma coluna a um modelo de dados. Editando o arquivo da migração, teríamos algo assim: Ð ×× ËØ ØÙ×ÌÓÈÖÓ Ø Ø Ú Ê ÓÖ Å Ö Ø ÓÒ × Ð ºÙÔ ÓÐÙÑÒ ÔÖÓ Ø×¸ Ø Ú ¸ ÓÓÐ Ò ÈÖÓ ØºÖ × Ø ÓÐÙÑÒ Ò ÓÖÑ Ø ÓÒ ÈÖÓ ØºÙÔ Ø ÐÐ Ø Ú ½ Ò × Ð º ÓÛÒ Ö ÑÓÚ ÓÐÙÑÒ ÔÖÓ Ø×¸ Ø Ú Ò Ò Nesse caso, estamos adicionando uma coluna e automaticamente atualizando para um valor que achamos mais indicado. Como o nosso modelo está sendo modificado, precisamos usar o método reset_column_information para que o Rails releia as tabelas e recarregue os modelos imediatamente. Na verdade, isso não é estritamente necessário pelo uso do método update_all, mas é interessante saber que esse uso pode ser necessário em alguns casos. O método update_all atualiza todos os registros usando o 88
  • 90. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF fragmento de SQL passado como parâmetro., pulando quaisquer validações existentes?portanto, use-o com cuidado. Após rodar o comando rake db:migrate, veremos o nosso banco atualizado completamente. Note que, nesse caso, a migração para um versão anterior simplesmente remove a coluna. 9.2 Usando Helpers Helpers são classes associadas a cada controller que contém funções utilitárias que são auto- maticamente exportadas para as views associadas ao mesmo. Cada controller tem o seu próprio helper e, a exemplo dos controllers, todos os helpers herdam métodos de uma classe base, que está definida no arquivo app/helpers/application_helper.rb. Olhando no diretório desse arquivo você pode ver que para cada controller, um helper já foi gerado. Precisamos de um método que receba um valor booleano e retorne um representação hu- mana disso. Como talvez precisemos usar esse método em outras views que não as da classe de projetos, seria mais interessante inserir o método no helper global da aplicação, modificando o arquivo application_helper.rb presente no diretório app/helpers. Teríamos, então, algo assim: ÑÓ ÙÐ ÔÔÐ Ø ÓÒÀ ÐÔ Ö Ý × ÓÖ ÒÓ ´Ú ÐÙ µ Ú ÐÙ × ÆÓ Ò Ò O método yes_or_no? está agora disponível para qualquer view na aplicação. Vamos usá-lo, modificando a nossa view: ½ ÈÖÓ Ø× » ½ ± Ð × ÒÓØ ℄ ± Ô ×ØÝÐ ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð ± Ð × ÒÓØ ℄ ± »Ô ± Ò ± Ô ± Ð Ò ØÓ Æ Û ÈÖÓ Ø ¸ Ø ÓÒ Ø ± »Ô Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø Æ Ñ »Ø Ø Ø Ú »Ø Ø Ø ÓÒ× »Ø »ØÖ ± ÔÖÓ Ø×º Ó ÔÖÓ Ø ± ØÖ Ø ± ÔÖÓ ØºÒ Ñ ± »Ø Ø ± Ý × ÓÖ ÒÓ ´ÔÖÓ Øº Ø Ú µ ± »Ø Ø ± Ð Ò ØÓ Ø ¸ Ø ÓÒ Ø ¸ ÔÖÓ Ø ± ÓÖ ± Ð Ò ØÓ Ð Ø ¸ ß Ø ÓÒ Ð Ø ¸ ÔÖÓ Ø ¸ ÓÒ ÖÑ Ö ÝÓÙ ×Ù »Ø »ØÖ ± Ò ± »Ø Ð 89
  • 91. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Note que podemos agora chamar o método definido no helper e também que temos um novo atributo na classe. Uma convenção especial do Rails é que, se um atributo representar um valor booleano, você pode acrescentar um ponto de interrogação após o método para que ele retorne verdadeiro ou falso diretamente. Isso acontece porque nem todos bancos de dados possuem campos boolea- nos nativos por padrão. No caso do MySQL, por exemplo, valores booleanos são representados por campos inteiros contendo zero ou um. O uso da interrogação facilita a visualização e uso do campo. Em várias situações, o Rails é capaz de detectar automaticamente o valor booleano, e o ponto de interrogação não é estritamente necessário. Mas é uma boa convenção fazer isso. Não só o código fica mais legível de imediato, como qualquer desenvolvedor Rails será capaz de dizer o tipo de dados armazenado no campo. O resultado agora é: Figura 29 Obviamente, precisamos editar o fato do projeto estar ativo ou não. Vamos alterar nossa view de edição: ½ ± ÔÖÓ ØºÒ Û Ö ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± ÈÖÓ Ø » ½ 90
  • 92. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ± ÖÖÓÖ Ñ ×× × ÓÖ ÔÖÓ Ø ± ± ר ÖØ ÓÖÑ Ø Ø ÓÒ Ø ¸ ÔÖÓ Ø ± Ô Ð Ð ÓÖ ÔÖÓ Ø Ò Ñ Æ Ñ »Ð Ð Ö ± Ø ÜØ Ð ÔÖÓ Ø ¸ Ò Ñ ± »Ô Ô Ð Ð ÓÖ ÔÖÓ Ø × Ö ÔØ ÓÒ × Ö ÔØ ÓÒ »Ð Ð Ö ± Ø ÜØ Ö ÔÖÓ Ø ¸ × Ö ÔØ ÓÒ ¸ ÖÓÛ× ± »Ô Ô Ð Ð ÓÖ ÔÖÓ Ø Ø Ú Ø Ú »Ð Ð Ö ± × Ð Ø ÔÖÓ Ø ¸ Ø Ú ¸ × ¸ ØÖÙ ℄¸ ÆÓ ¸ Ð× ℄℄ ± »Ô Ô ± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò Ð ¸ Ø ÓÒ Ð ×Ø ± »Ô ± Ò ÓÖÑ Ø ± Essa é uma das maneiras de editar o atributo, usando um elemento select. O método select gera automaticamente o código HTML necessário, recebendo parâmetros similares aos outros métodos e uma lista de valores a serem usados como escolhas. Esses valores são informados como um array de arrays onde cada item representa um par, contendo a descrição e o valor a ser atribuído. No caso acima, temos descrições Yes e No, correspondendo a valores true e false. O Rails define uma série de outros métodos capaz de gerar elementos select. Alguns des- ses métodos são especializados em gerar coleções aninhadas, por exemplo, enquanto outros geram diversos formatos de data. Antes de experimentar o método genérico acima, consulte a documentação para ver se existe algum método que lhe atenda. Lembre-se que, para valores booleanos, para que a atribuição funcione automaticamente, os valores true e false devem ser necessariamente usados. Caso contrário, a conversão automática de tipos do Ruby entra em ação e os dados não são processados apropriamente. O resultado pode ser visto abaixo e testando você verá que ele funciona perfeitamente, alte- rando os valores de acordo com sua escolha sem necessidade de qualquer codificação adicional: 91
  • 93. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 30 Existem pelo menos duas outras diretas maneiras de fazer a edição de um valor booleano. Uma seria usando radio buttons e checkboxes. Testar essas maneiras fica como um exercício para o leitor, lembrando que o princípio é o mesmo. Uma última coisa seria modificar o controller para gerar paginação automática. Isso é facil- mente conseguido com duas atualizações. Uma no controller: Ð ×× ÈÖÓ Ø× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø ÔÖÓ Ø Ô ×¸ ÔÖÓ Ø× Ô Ò Ø ÔÖÓ Ø×¸ Ô Ö Ô ¸ ÓÖ Ö Ò Ñ Ò Ø Ô Ö Ñ× ℄ ÔÖÓ Ø ÈÖÓ Øº Ò ´Ô Ö Ñ× ℄µ 92
  • 94. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ð× ÔÖÓ Ø ÈÖÓ ØºÒ Û Ò Ö ÕÙ ×ØºÔÓר ÔÖÓ Øº ØØÖ ÙØ × Ô Ö Ñ× ÔÖÓ Ø℄ ÔÖÓ Øº× Ú Ð × ÒÓØ ℄ Ì ÔÖÓ Ø Û × ×Ù ×× ÙÐÐÝ × Ú Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Ò Ð Ø ÈÖÓ Øº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ Ð × ÒÓØ ℄ Ì ÔÖÓ Ø Û × ×Ù ×× ÙÐÐÝ Ð Ø Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò E outra na view: ½ ÈÖÓ Ø× » ½ ± Ð × ÒÓØ ℄ ± Ô ×ØÝÐ ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð ± Ð × ÒÓØ ℄ ± »Ô ± Ò ± Ô ± Ð Ò ØÓ Æ Û ÈÖÓ Ø ¸ Ø ÓÒ Ø ± »Ô Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø Æ Ñ »Ø Ø Ø Ú »Ø Ø Ø ÓÒ× »Ø »ØÖ ± ÔÖÓ Ø×º Ó ÔÖÓ Ø ± ØÖ Ø ± ÔÖÓ ØºÒ Ñ ± »Ø Ø ± Ý × ÓÖ ÒÓ ´ÔÖÓ Øº Ø Ú µ ± »Ø Ø ± Ð Ò ØÓ Ø ¸ Ø ÓÒ Ø ¸ ÔÖÓ Ø ± ÓÖ ± Ð Ò ØÓ Ð Ø ¸ ß Ø ÓÒ Ð Ø ¸ ÔÖÓ Ø ¸ ÓÒ ÖÑ Ö ÝÓÙ ×Ù »Ø »ØÖ ± Ò ± »Ø Ð Ô ± Ô Ò Ø ÓÒ Ð Ò ×´ÔÖÓ Ø Ô ×µ ± »Ô A modificação no controller usa um método que já mencionamos anteriormente, paginate, para encapsular o processo de paginar os registros e gerar uma listagem de páginas (aqui sepa- radas em cinco registros por página). A modificação na view, por sua vez, simplesmente cria uma lista de páginas com base na informação retornada pelo método de paginação. 93
  • 95. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Os métodos usados são razoavelmente simples, mas, infelizmente, estão entre dois dos mais ineficientes do Rails e devem ser usados com cuidado. No momento, entretando, com a quan- tidade de dados que temos, eles não chegam a representar um problema. O resultado depois pode ser visto abaixo. Visualizando a primeira página, temos: Figura 31 E em seguida, a segunda página (note o parâmetro adicional da URL): 94
  • 96. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 32 Terminamos um controller completo - simples, mas funcional - e, inclusive, alteramos o modelo de dados por trás do mesmo de acordo com nossa necessidade. Agora já temos uma base para investigarmos o próximo passo de uma aplicação: relaciona- mentos entre classes de dados. 95
  • 97. Capítulo 10 Relacionamentos Essa lição tem como objetivo mostrar o que são relacionamentos. 10.1 Início Antes de começarmos a ver os relacionamentos, vamos unir o nosso projeto sob um layout que pelo menos nos permita navegar mais facilmente. Nosso novo arquivo app/views/layouts/application.rb ficaria assim: ØÑÐ Ø ØÐ Ì »Ø ØÐ ± רÝÐ × Ø Ð Ò Ø ÙÐØ ± ± רÝÐ × Ø Ð Ò Ø × ÓÐ ± » Ó Ý ½ Ö Ì » ½ ÙÐ Ñ ÒÙ Ð ± Ð Ò ØÓ ÙÒÐ ×× ÙÖÖ ÒØ ²Ö ÕÙÓ ÓÒØ ÜØ× ¸ ÓÒØÖÓÐÐ Ö ÓÒØ ÜØ× ± »Ð Ð ± Ð Ò ØÓ ÙÒÐ ×× ÙÖÖ ÒØ ²Ö ÕÙÓ ÈÖÓ Ø× ¸ ÓÒØÖÓÐÐ Ö ÔÖÓ Ø× ± »Ð »ÙÐ Ú ÓÒØ ÒØ× ± Ý Ð ± » Ú » Ó Ý » ØÑÐ E a stylesheet que estamos usando, default.css, dessa maneira: Ó Ý ß ÓÒØ¹ Ñ ÐÝ Î Ö Ò ¸ Ö Ð¸ × Ò×¹× Ö ÓÒØ¹× Þ ½¼¼± Ñ Ö Ò ¼ Ô Ò ¼ ½ Ö ß 96
  • 98. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÖÓÙÒ ¹ ÓÐÓÖ ÓÐÓÖ Û Ø Ô Ò ½¼ÔÜ ½¼ÔÜ ½ ÔÜ Ñ Ö Ò ¼ ÙÐ Ñ ÒÙ ß Ô Ò ÔÜ ½¼ÔÜ Ñ Ö Ò ¼ ÓÖ Ö¹ ÓØØÓÑ ½ÔÜ ×ÓÐ ÙÐ Ñ ÒÙ Ð ß ×ÔÐ Ý ÒÐ Ò Ñ Ö Ò¹Ö Ø ÔÜ ÓÒØ¹Û Ø ÓÐ ÙÐ Ñ ÒÙ ß Ø ÜØ¹ ÓÖ Ø ÓÒ ÒÓÒ ÓÒØ¹Û Ø ÒÓÖÑ Ð Ú ÓÒØ ÒØ× ß Ñ Ö Ò ½¼ÔÜ Ú ÓÒØ ÒØ× ½ ß ÓÒØ¹× Þ ½¿¼± ÓÒØ¹×ØÝÐ Ø Ð O resultado final seria: 97
  • 99. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 33 Não é perfeito por causa de alguns defeitos no código HTML (como o uso de dois elementos H1 na página, tabelas com estilos aplicados diretamente, etc) e pelo uso da stylesheet scaf- fold.css, mas já é uma melhoria (desconsiderando, é claro, o fato de que eu não entendo nada de design gráfico). Modificações do primeiro scaffold gerado para contextos ficam como um exer- cício para o leitor. O objetivo é demonstrar como podemos atualizar a aplicação sem mexer em qualquer dos controllers e views posteriormente geradas uma vez que elas tenham sido bem planejadas. Para exemplificarmos os relacionamentos, vamos começar com o cadastro de ações. Uma ação pertence a um projeto e é executado em um determinado contexto. Isso é suficiente para começarmos o nosso cadastro. Atualizamos primeiro o arquivo application.rhtml para incluir a nossa nova área, temos: ØÑÐ Ø ØÐ Ì »Ø ØÐ ± רÝÐ × Ø Ð Ò Ø ÙÐØ ± ± רÝÐ × Ø Ð Ò Ø × ÓÐ ± » 98
  • 100. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ó Ý ½ Ö Ì » ½ ÙÐ Ñ ÒÙ Ð ± Ð Ò ØÓ ÙÒÐ ×× ÙÖÖ ÒØ ²Ö ÕÙÓ ÓÒØ ÜØ× ¸ ÓÒØÖÓÐÐ Ö ÓÒØ ÜØ× ¸ Ø ÓÒ Ð ± Ð Ò ØÓ ÙÒÐ ×× ÙÖÖ ÒØ ²Ö ÕÙÓ ÈÖÓ Ø× ¸ ÓÒØÖÓÐÐ Ö ÔÖÓ Ø× ¸ Ø ÓÒ Ð ± Ð Ò ØÓ ÙÒÐ ×× ÙÖÖ ÒØ ²Ö ÕÙÓ Ø ÓÒ× ¸ ÓÒØÖÓÐÐ Ö Ø ÓÒ× ¸ Ø ÓÒ Ð »ÙÐ Ú ÓÒØ ÒØ× ± Ý Ð ± » Ú » Ó Ý » ØÑÐ Em segundo lugar, geramos o nosso controller. Vamos seguir o mesmo estilo do controller usado para projetos: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» Ò Ö Ø ÓÒØÖÓÐÐ Ö Ø ÓÒ× Ò Ü Ð ×Ø Ø Ð Ø Ü ×Ø× ÔÔ» ÓÒØÖÓÐÐ Ö×» Ü ×Ø× ÔÔ» ÐÔ Ö×» Ö Ø ÔÔ»Ú Û×» Ø ÓÒ× Ü ×Ø× Ø ×Ø» ÙÒ Ø ÓÒ Ð» Ö Ø ÔÔ» ÓÒØÖÓÐÐ Ö×» Ø ÓÒ× ÓÒØÖÓÐÐ ÖºÖ Ö Ø Ø ×Ø» ÙÒ Ø ÓÒ Ð» Ø ÓÒ× ÓÒØÖÓÐÐ Ö Ø ×ØºÖ Ö Ø ÔÔ» ÐÔ Ö×» Ø ÓÒ× ÐÔ ÖºÖ Ö Ø ÔÔ»Ú Û×» Ø ÓÒ×» Ò ÜºÖ ØÑÐ Ö Ø ÔÔ»Ú Û×» Ø ÓÒ×»Ð ×ØºÖ ØÑÐ Ö Ø ÔÔ»Ú Û×» Ø ÓÒ×» ØºÖ ØÑÐ Ö Ø ÔÔ»Ú Û×» Ø ÓÒ×» Ð Ø ºÖ ØÑÐ Para facilitar, vamos duplicar a funcionalidade presente no cadastro de projetos. O nosso controller de ações ficaria assim, inicialmente: Ð ×× Ø ÓÒ× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø Ø ÓÒ Ô ×¸ Ø ÓÒ× Ô Ò Ø Ø ÓÒ׸ Ô Ö Ô ¸ ÓÖ Ö × Ö ÔØ ÓÒ Ò Ø Ô Ö Ñ× ℄ Ø ÓÒ Ø ÓÒº Ò ´Ô Ö Ñ× ℄µ Ð× Ø ÓÒ Ø ÓÒºÒ Û Ò Ö ÕÙ ×ØºÔÓר Ø ÓÒº ØØÖ ÙØ × Ô Ö Ñ× Ø ÓÒ℄ Ø ÓÒº× Ú Ð × ÒÓØ ℄ Ì Ø ÓÒ Û × ×Ù ×× ÙÐÐÝ × Ú Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø 99
  • 101. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ò Ò Ò Ð Ø Ø ÓÒº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ Ð × ÒÓØ ℄ Ì Ø ÓÒ Û × ×Ù ×× ÙÐÐÝ Ð Ø Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Seguido por nossa view de listagem, que ficaria assim: ½ Ø ÓÒ× » ½ ± Ð × ÒÓØ ℄ ± Ô ×ØÝÐ ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð ± Ð × ÒÓØ ℄ ± »Ô ± Ò ± Ô ± Ð Ò ØÓ Æ Û Ø ÓÒ ¸ Ø ÓÒ Ø ± »Ô Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø × Ö ÔØ ÓÒ »Ø Ø ÓÒ »Ø Ø Ø ÓÒ× »Ø »ØÖ ± Ø ÓÒ׺ Ó Ø ÓÒ ± ØÖ Ø ± Ø ÓÒº × Ö ÔØ ÓÒ ± »Ø Ø ± Ý × ÓÖ ÒÓ ´ Ø ÓÒº ÓÒ µ ± »Ø Ø ± Ð Ò ØÓ Ø ¸ Ø ÓÒ Ø ¸ Ø ÓÒ ± ÓÖ ± Ð Ò ØÓ Ð Ø ¸ ß Ø ÓÒ Ð Ø ¸ Ø ÓÒ ¸ ÓÒ ÖÑ Ö ÝÓÙ ×ÙÖ »Ø »ØÖ ± Ò ± »Ø Ð Ô ± Ô Ò Ø ÓÒ Ð Ò ×´ Ø ÓÒ Ô ×µ ± »Ô Em, por fim, da nossa view de edição, que seria: ½ ± Ø ÓÒºÒ Û Ö ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± Ø ÓÒ » ½ ± ÖÖÓÖ Ñ ×× × ÓÖ Ø ÓÒ ± ± ר ÖØ ÓÖÑ Ø Ø ÓÒ Ø ¸ Ø ÓÒ ± Ô Ð Ð ÓÖ Ø ÓÒ × Ö ÔØ ÓÒ × Ö ÔØ ÓÒ »Ð Ð Ö ± Ø ÜØ Ö Ø ÓÒ ¸ × Ö ÔØ ÓÒ ¸ ÖÓÛ× ± »Ô Ô Ð Ð ÓÖ Ø ÓÒ ÓÒ ÓÒ »Ð Ð Ö ± × Ð Ø Ø ÓÒ ¸ ÓÒ ¸ × ¸ ØÖÙ ℄¸ ÆÓ ¸ Ð× ℄℄ ± »Ô 100
  • 102. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ô ± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò Ð ¸ Ø ÓÒ Ð ×Ø ± »Ô ± Ò ÓÖÑ Ø ± Não tente usar essa view para salvar uma ação ainda. Há um erro sutil na mesma que discu- tiremos mais adiante. As demais views geradas (index.rhtml e delete.rhtml) podem ser removidas da aplicação pois não serão usadas. Obviamente, a view acima não inclui todos os atributos presentes na ação. Para incluirmos esses atributos, vamos considerar algumas coisas. O atributos created_at representa a data de criação da ação. Atributos terminados em _at e _on são automaticamente reconhecidos pelo Rails como representando datas e tempos, respec- tivamente. Além disso, atributos com os nomes created_at, created_on, updated_at e update_on serão automaticamente atualizados pelo Rails de acordo com a necessidade. Todos quando o objeto for criado e os dois últimos sempre que o objeto for salvo. Como o Rails obviamente não tem controle sobre o banco de dados, o desenvolvedor é que deve escolher o tipo de dados certo para os mesmos no banco, usando date no caso dos termina- dos em _at e datetime no caso dos terminados em _on (tipos de dados do MySQL, é claro-adapte conforme a necessidade). Apesar disso, usar um tipo mais ou menos preciso não causa erros e Rails tentará conversões sempre que necessário. No nosso caso, então, não precisamos dar qualquer valor ao atributo created_at para que ele seja salvo. Na verdade, como esse é um campo que deveria ser salvo uma única vez, vamos colocar alguma informação no modelo para que o mesmo não possa ser atribuído em formulários, mas somente em código direto. Ð ×× Ø ÓÒ Ø Ú Ê ÓÖ × ØØÖ ÔÖÓØ Ø Ö Ø Ø Ò Esse declaração impede que esse atributo seja atualizado automaticamente por qualquer atribuição via formulários ou métodos provindos do servidor. Somente uma atualização direta via código funcionará e como não precisamos disso, não temos que nos preocupar mais com esse atributo. O reverso dessa declaração seria attr_accessible. O atributo completed_at representa a data em que a ação foi completada. Também não pre- cisamos editá-lo em nossa view, já que ele poderia ser atribuído quando o usuário marcasse a ação como completada. Faremos então a mesma coisa com esse atributo, mudando o nosso modelo para: Ð ×× Ø ÓÒ Ø Ú Ê ÓÖ × ØØÖ ÔÖÓØ Ø Ö Ø Ø¸ ÓÑÔÐ Ø Ø Ò Como o campo é atribuído automaticamente, o que precisamos fazer é achar alguma forma de modificar esse atributo quando o atributo done, que representa o fato da ação estar completa, for marcado como verdadeiro. A solução é sobrescrever o método de escrita do atributo done, algo que o Rails permite justamente para esse tipo de situação: Ð ×× Ø ÓÒ Ø Ú Ê ÓÖ × ØØÖ ÔÖÓØ Ø Ö Ø Ø¸ ÓÑÔÐ Ø Ø 101
  • 103. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÓÒ ´Ú ÐÙ µ Ø Ú Ê ÓÖ ÓÒÒ Ø ÓÒ ÔØ Ö× ÓÐÙÑÒºÚ ÐÙ ØÓ ÓÓÐ Ò´Ú ÐÙ µ × Ð º ÓÑÔÐ Ø Ø Ø Ì Ñ ºÒÓÛ Ð× × Ð º ÓÑÔÐ Ø Ø Ò Ð Ò ÛÖ Ø ØØÖ ÙØ ´ ÓÒ ¸ Ú ÐÙ µ Ò Ò Aqui, estamos usando o momento em que o atributo done é recebido e executando ações extras. Note o sinal de igual, indicando que esse é um método de atribuição; no Ruby, qualquer método terminado com o sinal pode ser automaticamente usado como se fosse um atributo. O método verifica se valor recebido foi verdadeiro usando um método interno do ActiveRecord. Essa chamada é necessária porque, exceto por nil e false, qualquer outro valor é considerado verdadeiro em Ruby, incluindo zero e strings vazias. Se sim, o atributo completed_at é atualizado com a data atual. Se não, o atributo é retornado a um valor nulo. Depois disso, o valor recebido para o atributo done é passado sem modificações para a camada de banco de dados, usando o método write_attribute. Mesmo que você não precise modificar campos em dependência um do outro, a técnica acima é util para guardar valores convertidos (por exemplo, um valor que é informado em graus, mas armazenado em radianos ou vice-versa). O par de métodos write_attribute/read_attribute pode ser usado em conjunção com métodos que sobrescrevem os métodos de acesso que o Rails gera para permitir maior flexibilidade da manipulação de dados. Finalmente, temos os atributos context_id e project_id, que representam as chaves estran- geiras que criamos no banco, que usaremos para os nossos primeiros relacionamentos entre classes. 102
  • 104. Capítulo 11 Belongs to Nessa lição falaremos de Belongs to. 11.1 Belongs to No caso desses dois atributos, poderíamos dizer que uma ação pertence a um contexto e que pertence a um projeto. No Rails, representaríamos isso da seguinte forma: Ð ×× Ø ÓÒ Ø Ú Ê ÓÖ × ØØÖ ÔÖÓØ Ø Ö Ø Ø¸ ÓÑÔÐ Ø Ø ÓÒ ´Ú ÐÙ µ Ø Ú Ê ÓÖ ÓÒÒ Ø ÓÒ ÔØ Ö× ÓÐÙÑÒºÚ ÐÙ ØÓ ÓÓÐ Ò´Ú ÐÙ µ × Ð º ÓÑÔÐ Ø Ø Ø Ì Ñ ºÒÓÛ Ð× × Ð º ÓÑÔÐ Ø Ø Ò Ð Ò ÛÖ Ø ØØÖ ÙØ ´ ÓÒ ¸ Ú ÐÙ µ Ò ÐÓÒ × ØÓ ÓÒØ ÜØ ÐÓÒ × ØÓ ÔÖÓ Ø Ò Essas duas declarações são suficientes para criar uma série de facilidades no Rails que inclui atribuições e buscas. Veja que você não precisou dizer nada sobre relacionamento além do que ele referencia. O Rails é capaz de deduzir a chave estrangeira quando ela for criada concate- nando o nome da tabela pai ao sufixo _id. Caso você tenha dado outro nome, você pode também dizer ao Rails qual seria a chave estrangeira usando algo assim: ÐÓÒ × ØÓ ×٠ظ ÓÖ Ò Ý Ø ÓÖÝ Além dessa possibilidade, há outras opções na definição de um relacionamento que valem a pena ser exploradas na documentação, incluindo outras condições limítrofes para o mesmo. Para cada relacionamento criado, o Rails disponibiliza métodos que permitem testar a exis- tência de uma associação, defini-la, removê-la e buscá-la. Vamos usar o console para testar isso: 103
  • 105. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» ÓÒ×ÓÐ ÄÓ Ò Ú ÐÓÔÑ ÒØ ÒÚ ÖÓÒÑ ÒØº Ø ÓÒ Ø ÓÒº Ö Ø ´ × Ö ÔØ ÓÒ Ø ×Ø Ø ÓÒº µ Ø ÓÒ ¼Ü ¿ ¿ Ò Û Ö ÓÖ Ð× ¸ ÖÖÓÖ× Ø Ú Ê ÓÖ ÖÖÓÖ× ¼Ü ¾ ¼ × Ø ÓÒ ¼Ü ¿ ¿ ººº ¸ ÖÖÓÖ× ß ¸ ØØÖ ÙØ × ß ÓÒØ ÜØ Ò Ð¸ ÓÑÔÐ Ø Ø ÔÖÓ Ø Ò Ð¸ ÓÒ Ò Ð¸ ¸ × Ö ÔØ ÓÒ Ø ×Ø Ø ÓÒº ¸ Ö Ø Ø Ì Ù Ë ½ ¾ ¿ ÊÌ ¾¼¼ Ì ÑÓ× ÙÑ Ó × ÐÚ º Ø ÓÒºÔÖÓ Ø Ò Ð Ø ÓÒº ÓÒØ ÜØ Ò Ð Ø ÓÒºÔÖÓ Ø Ò Ð Ø ÓÒº ÓÒØ ÜØ Ò Ð Com o relacionamento, em adição aos atributos vindos do banco de dados temos agora outros dois atributos que representam a relação. Podemos atribui-los normalmente: Ø ÓÒº ÓÒØ ÜØ ½ ½ Ø ÓÒº ÓÒØ ÜØ ÓÒØ ÜØ ¼Ü ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½ Ou usar diretamente a relação: Ø ÓÒºÔÖÓ Ø ÈÖÓ Øº Ò ´½µ ÈÖÓ Ø ¼Ü ¾ ØØÖ ÙØ × ß Ò Ñ Ù Ð ÀÓÙ× ¸ ½ ¸ × Ö ÔØ ÓÒ Ù Ð Ö Ñ ÓÙ× ÒØ Ö ÐÝ ÔÐ ÒÒ Ý ÑÝ× Ð ¸ Ò ÐÙ Ò ÒØ Ö ×Ø Ò ØØ Û Ø Ù Ð Ö Öݺ ¸ Ø Ú ½ Ø ÓÒºÔÖÓ Ø ½ Se quisermos, podemos criar também novos valores diretamente: Ø ÓÒº ÓÒØ ÜØ ÓÒØ ÜØº Ö Ø ´ Ò Ñ È ÓÒ µ ÓÒØ ÜØ ¼Ü ½ ¼ Ò Û Ö ÓÖ Ð× ¸ ÖÖÓÖ× Ø Ú Ê ÓÖ ÖÖÓÖ× ¼Ü × ÓÒØ ÜØ ¼Ü ½ ¼ ººº ¸ ÖÖÓÖ× ß ¸ ØØÖ ÙØ × ß Ò Ñ È ÓÒ ¸ ¿ Relacionamentos são bem úteis, mas precisamos ter um pouco de cuidado em como os usa- mos. Aqui entra a necessidade de conhecimento de SQL que mencionamos anteriormente. Veja o caso abaixo, por exemplo: Ø ÓÒº Ò ´ µºÔÖÓ ØºÒ Ñ Ù Ð ÀÓÙ× 104
  • 106. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Se executarmos a ação acima e e observamos o log de desenvolvimento gerado pelo Rails (que está em log/development.log), veremos o seguinte: Ø ÓÒ ÄÓ ´¼º¼¼¾ ½µ Ë Ä Ì ¶ ÊÇÅ Ø ÓÒ× ÏÀ Ê ´ Ø ÓÒ׺ µ ÄÁÅÁÌ ½ ÈÖÓ Ø ÄÓ ´¼º¼¼½¾ µ Ë Ä Ì ¶ ÊÇÅ ÔÖÓ Ø× ÏÀ Ê ´ÔÖÓ Ø×º ½µ ÄÁÅÁÌ ½ Isso mostra que duas chamadas foram feitas ao banco para carregar o nome do projeto da ação buscada, uma delas completamente desnecessária. Obviamente, se fizermos isso em um loop, com múltiplos objetos e relacionamentos, o nível de ineficiência subirá rapidamente. Para isso, o Rails tem uma solução que resolve a maior parte dos problemas causados por isso, gerando joins automaticamente de acordo com o que o usuário precisa. Por exemplo: Ø ÓÒº Ò ´ ¸ Ò ÐÙ ÔÖÓ Ø¸ ÓÒØ ÜØ℄µ Ø ÓÒ ¼Ü ¼ ÓÒØ ÜØ ÓÒØ ÜØ ¼Ü ½ ØØÖ ÙØ × ß Ò Ñ È ÓÒ ¸ ¿ ÔÖÓ Ø ÈÖÓ Ø ¼Ü ØØÖ ÙØ × ß Ò Ñ Ù Ð ÀÓÙ× ¸ ½ ¸ × Ö ÔØ ÓÒ Ö Ñ ÓÙ× ÒØ Ö ÐÝ ÔÐ ÒÒ Ý ÑÝ× Ð ¸ Ò ÐÙ Ò ÒØ Ö ×Ø Ò ØØ Û Ø Ù Ð Ö Öݺ Ø Ú ½ ¸ ØØÖ ÙØ × ß ÓÒØ ÜØ ¿ ¸ ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ Ø ½ ¸ ÓÒ ¸ × Ö ÔØ ÓÒ Ø ×Ø Ø ÓÒº ¸ Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¾ ¿ Como você pode ver, tanto o contexto como o projeto foram automaticamente recuperados. Se observamos o log, veremos o seguinte: Ø ÓÒ ÄÓ ÁÒ ÐÙ Ò ××Ó Ø ÓÒ× ´¼º¾¿¾¼ ¾µ Ë Ä Ì Ø ÓÒ׺ Ë Ø¼ Ö¼¸ Ø ÓÒ׺ × Ë Ø¼ Ö½¸ Ø ÓÒ׺ ÓÒ Ë Ø¼ Ö¾¸ Ø ÓÒ׺ Ö Ø Ø Ë Ø¼ Ö¿¸ Ø ÓÒ׺ ÓÑÔÐ Ø Ø Ë Ø Ø ÓÒ׺ ÓÒØ ÜØ Ë Ø¼ Ö ¸ Ø ÓÒ׺ ÔÖÓ Ø Ë Ø¼ Ö ¸ ÔÖÓ Ø×º Ë Ø½ Ö¼¸ ÔÖÓ Ø Ë Ø½ Ö½¸ ÔÖÓ Ø×º × Ö ÔØ ÓÒ Ë Ø½ Ö¾¸ ÔÖÓ Ø×º Ø Ú Ë Ø½ Ö¿¸ ÓÒØ ÜØ×º Ë Ø¾ Ö¼ ÓÒØ ÜØ×º Ò Ñ Ë Ø¾ Ö½ ÊÇÅ Ø ÓÒ× Ä Ì ÇÍÌ Ê ÂÇÁÆ ÔÖÓ Ø× ÇÆ ÔÖÓ Ø×º Ø ÓÒ׺ÔÖÓ Ä Ì ÇÍÌ Ê ÂÇÁÆ ÓÒØ ÜØ× ÇÆ ÓÒØ ÜØ×º Ø ÓÒ׺ ÓÒØ ÜØ ÏÀ Ê ´ Ø ÓÒ׺ µ Ao invés de duas declaração temos somente uma. Para relacionamentos múltiplos, isso pode reduzir centenas ou milhares de chamadas ao banco em uma única chamada. Veja por exemplo a diferença entre as duas chamadas abaixo, depois de criarmos três ações: Ø ÓÒº Ò ´ Ðеº ÓÐÐ Ø ß ºÔÖÓ ØºÒ Ñ ¸ º ÓÒØ ÜØºÒ Ñ ℄ Ù Ð ÀÓÙ× ¸ ÀÓÑ ℄¸ ÈÐ ÒØ ÌÖ ¸ ÏÓÖ ℄¸ ÏÖ Ø ÓÓ ¸ ÀÓÑ ℄℄ O objetivo da chamada é retornar uma coleção dos nomes dos projetos e contextos de cada ação existe no banco, em pares. A chamada acima gera os seguintes comandos: Ø ÓÒ ÄÓ ´¼º¼¼¾ ¿ µ Ë Ä Ì ¶ ÊÇÅ Ø ÓÒ× ÈÖÓ Ø ÄÓ ´¼º¼¼¾½ ½µ Ë Ä Ì ¶ ÊÇÅ ÔÖÓ Ø× ÏÀ Ê ´ÔÖÓ Ø×º ½µ ÄÁÅÁÌ ½ ÓÒØ ÜØ ÄÓ ´¼º¼¼¼ ¿ µ Ë Ä Ì ¶ ÊÇÅ ÓÒØ ÜØ× ÏÀ Ê ´ ÓÒØ ÜØ×º ½µ ÄÁÅÁÌ ½ ÈÖÓ Ø ÄÓ ´¼º¼¼½¾¾¼µ Ë Ä Ì ¶ ÊÇÅ ÔÖÓ Ø× ÏÀ Ê ´ÔÖÓ Ø×º ¾µ ÄÁÅÁÌ ½ ÓÒØ ÜØ ÄÓ ´¼º¼¼½½½ µ Ë Ä Ì ¶ ÊÇÅ ÓÒØ ÜØ× ÏÀ Ê ´ ÓÒØ ÜØ×º ¾µ ÄÁÅÁÌ ½ ÈÖÓ Ø ÄÓ ´¼º¼¼½¾¾ µ Ë Ä Ì ¶ ÊÇÅ ÔÖÓ Ø× ÏÀ Ê ´ÔÖÓ Ø×º ¿µ ÄÁÅÁÌ ½ ÓÒØ ÜØ ÄÓ ´¼º¼¼½¼ µ Ë Ä Ì ¶ ÊÇÅ ÓÒØ ÜØ× ÏÀ Ê ´ ÓÒØ ÜØ×º ½µ ÄÁÅÁÌ ½ Agora, vamos mudar a chamada para: 105
  • 107. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ø ÓÒº Ò ´ Ðи Ò ÐÙ ÔÖÓ Ø¸ ÓÒØ ÜØ℄µº ÓÐÐ Ø ß ºÔÖÓ ØºÒ Ñ ¸ º ÓÒØ Ù Ð ÀÓÙ× ¸ ÀÓÑ ℄¸ ÈÐ ÒØ ÌÖ ¸ ÏÓÖ ℄¸ ÏÖ Ø ÓÓ ¸ ÀÓÑ ℄℄ Veremos, ao executá-la, que somente uma chamada será feita: Ø ÓÒ ÄÓ ÁÒ ÐÙ Ò ××Ó Ø ÓÒ× ´¼º¼¼ ½ µ Ë Ä Ì Ø ÓÒ׺ Ë Ø¼ Ö¼¸ Ø ÓÒ׺ × Ö Ë Ø¼ Ö½¸ Ø ÓÒ׺ ÓÒ Ë Ø¼ Ö¾¸ Ø ÓÒ׺ Ö Ø Ø Ë Ø¼ Ö¿¸ Ø ÓÒ׺ ÓÑÔÐ Ø Ø Ë Ø Ø ÓÒ׺ ÓÒØ ÜØ Ë Ø¼ Ö ¸ Ø ÓÒ׺ ÔÖÓ Ø Ë Ø¼ Ö ¸ ÔÖÓ Ø×º Ë Ø½ Ö¼¸ ÔÖÓ Ø Ë Ø½ Ö½¸ ÔÖÓ Ø×º × Ö ÔØ ÓÒ Ë Ø½ Ö¾¸ ÔÖÓ Ø×º Ø Ú Ë Ø½ Ö¿¸ ÓÒØ ÜØ×º Ë Ø¾ Ö¼ ÓÒØ ÜØ×º Ò Ñ Ë Ø¾ Ö½ ÊÇÅ Ø ÓÒ× Ä Ì ÇÍÌ Ê ÂÇÁÆ ÔÖÓ Ø× ÇÆ ÔÖÓ Ø×º Ø ÓÒ׺ÔÖÓ Ä Ì ÇÍÌ Ê ÂÇÁÆ ÓÒØ ÜØ× ÇÆ ÓÒØ ÜØ×º Ø ÓÒ׺ ÓÒØ ÜØ É fácil ver que essa chamada é bem melhor do que as demais e isso considerando alguns poucos registros. Em casos de modelos mais complexos, a partir do Rails 1.1 a declaração include é recursiva. Você poderia ter algo como: ÓÖ Ö× ÇÖ Ñº Ò Ðи Ò ÐÙ Ø Ñ× ß ÔÖÓ Ù Ø¸ × ÓÙÒØ ¸ × Ð ×Ô Ö×ÓÒ℄ O código acima buscaria todas as ordens de compra presentes em um banco de dados, carre- gando automaticamente seus itens e a pessoa que a vendeu. Além disso, para os itens, também carregaria os objetos descrevendo o produto associado e o desconto dado. As combinações são infinitas e basta você manter a possibilidade em mente para aplicá-la em suas próprias aplica- ções. Vamos agora introduzir nossa modificação final em nosso modelo de dados, as validações: Ð ×× Ø ÓÒ Ø Ú Ê ÓÖ × ØØÖ ÔÖÓØ Ø Ö Ø Ø¸ ÓÑÔÐ Ø Ø ÓÒ ´Ú ÐÙ µ Ø Ú Ê ÓÖ ÓÒÒ Ø ÓÒ ÔØ Ö× ÓÐÙÑÒºÚ ÐÙ ØÓ ÓÓÐ Ò´Ú ÐÙ µ × Ð º ÓÑÔÐ Ø Ø Ø Ì Ñ ºÒÓÛ Ð× × Ð º ÓÑÔÐ Ø Ø Ò Ð Ò ÛÖ Ø ØØÖ ÙØ ´ ÓÒ ¸ Ú ÐÙ µ Ò ÐÓÒ × ØÓ ÓÒØ ÜØ ÐÓÒ × ØÓ ÔÖÓ Ø Ú Ð Ø × ÔÖ × Ò Ó × Ö ÔØ ÓÒ Ú Ð Ø × ÔÖ × Ò Ó ÓÒØ ÜØ Ú Ð Ø × ÔÖ × Ò Ó ÔÖÓ Ø Ò Agora que temos os nossos relacionamentos, podemos atualizar o nosso controller e as views geradas para o mesmo. Primeiro, o controller: Ð ×× Ø ÓÒ× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø 106
  • 108. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø Ø ÓÒ Ô ×¸ Ø ÓÒ× Ô Ò Ø Ø ÓÒ׸ Ô Ö Ô ¸ ÓÖ Ö × Ö ÔØ ÓÒ Ò Ø ÓÒØ ÜØ× ÓÒØ ÜØº Ò ´ Ðи ÓÖ Ö Ò Ñ µº ÓÐÐ Ø ß ºÒ Ñ ¸ º ℄ ÔÖÓ Ø× ÈÖÓ Øº Ò ´ Ðи ÓÖ Ö Ò Ñ µº ÓÐÐ Ø ß ºÒ Ñ ¸ º ℄ Ô Ö Ñ× ℄ Ø ÓÒ Ø ÓÒº Ò ´Ô Ö Ñ× ℄µ Ð× Ø ÓÒ Ø ÓÒºÒ Û Ò Ö ÕÙ ×ØºÔÓר Ø ÓÒº ØØÖ ÙØ × Ô Ö Ñ× Ø ÓÒ℄ Ø ÓÒº× Ú Ð × ÒÓØ ℄ Ì Ø ÓÒ Û × ×Ù ×× ÙÐÐÝ × Ú Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Ò Ð Ø Ø ÓÒº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ Ð × ÒÓØ ℄ Ì Ø ÓÒ Û × ×Ù ×× ÙÐÐÝ Ð Ø Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò As duas linhas acrescentadas criam arrays de pares com os nomes e identificadores dos objetos buscados. Precisamos desses arrays para a nossa view de edição, como vemos abaixo: ½ ± Ø ÓÒºÒ Û Ö ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± Ø ÓÒ » ½ ± ÖÖÓÖ Ñ ×× × ÓÖ Ø ÓÒ ± ± ר ÖØ ÓÖÑ Ø Ø ÓÒ Ø ¸ Ø ÓÒ ± Ô Ð Ð ÓÖ Ø ÓÒ × Ö ÔØ ÓÒ × Ö ÔØ ÓÒ »Ð Ð Ö ± Ø ÜØ Ö Ø ÓÒ ¸ × Ö ÔØ ÓÒ ¸ ÖÓÛ× ± »Ô Ô Ð Ð ÓÖ Ø ÓÒ ÓÒ ÓÒ »Ð Ð Ö ± × Ð Ø Ø ÓÒ ¸ ÓÒ ¸ × ¸ ØÖÙ ℄¸ ÆÓ ¸ Ð× ℄℄ ± »Ô Ô Ð Ð ÓÖ Ø ÓÒ ÓÒØ ÜØ ÓÒØ ÜØ »Ð Ð Ö ± × Ð Ø Ø ÓÒ ¸ ÓÒØ ÜØ ¸ ÓÒØ ܨ׏ ÔÖÓÑÔØ ¹¹ ÓÓ× ¹¹ ± »Ô Ô Ð Ð ÓÖ Ø ÓÒ ÔÖÓ Ø ÈÖÓ Ø »Ð Ð Ö ± × Ð Ø Ø ÓÒ ¸ ÔÖÓ Ø ¸ ÔÖÓ Ø×¸ ÔÖÓÑÔØ ¹¹ ÓÓ× ¹¹ ± 107
  • 109. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF »Ô Ô ± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò Ð ¸ Ø ÓÒ Ð ×Ø ± »Ô ± Ò ÓÖÑ Ø ± Selecionar os objetos e gerar as estruturas que precisamos no controller é um prática reco- mendada porque mantemos a nossa view limpa e podemos fazer quaisquer ordenações e filtros sem nos preocuparmos com o design da aplicação. O parâmetro prompt, passado acima, permite que um indicador da seleção apareça antes dos valores propriamente ditos. O formulário resultante fica assim: Figura 34 Agora voltamos ao pequeno problema que indicamos existir nesse controller anteriormente. Se você tentar salvar uma ação agora, verá que um erro acontece: 108
  • 110. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 35 Esse erro é causado por um detalhe. No Rails, a chave params[:action] já é tomada pelo nome da ação que está sendo executada e como temos um objeto com esse nome, acabamos com um problema. Entretanto, a solução é simples: basta renomear o nosso objeto. Podemos, por exemplo, chamá-lo de item. Primeiro, mudamos o controller: Ð ×× Ø ÓÒ× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø Ø ÓÒ Ô ×¸ Ø ÓÒ× Ô Ò Ø Ø ÓÒ׸ Ô Ö Ô ¸ ÓÖ Ö × Ö ÔØ ÓÒ Ò Ø ÓÒØ ÜØ× ÓÒØ ÜØº Ò ´ Ðи ÓÖ Ö Ò Ñ µº ÓÐÐ Ø ß ºÒ Ñ ¸ º ℄ ÔÖÓ Ø× ÈÖÓ Øº Ò ´ Ðи ÓÖ Ö Ò Ñ µº ÓÐÐ Ø ß ºÒ Ñ ¸ º ℄ Ô Ö Ñ× ℄ 109
  • 111. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ø Ñ Ø ÓÒº Ò ´Ô Ö Ñ× ℄µ Ð× Ø Ñ Ø ÓÒºÒ Û Ò Ö ÕÙ ×ØºÔÓר Ø Ñº ØØÖ ÙØ × Ô Ö Ñ× Ø Ñ℄ Ø Ñº× Ú Ð × ÒÓØ ℄ Ì Ø ÓÒ Û × ×Ù ×× ÙÐÐÝ × Ú Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Ò Ð Ø Ø ÓÒº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ Ð × ÒÓØ ℄ Ì Ø ÓÒ Û × ×Ù ×× ÙÐÐÝ Ð Ø Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò E depois mudamos a view: ½ ± Ø ÑºÒ Û Ö ÓÖ ± Æ Û ± Ð× ± Ø Ò ± Ò ± Ø ÓÒ » ½ ± ÖÖÓÖ Ñ ×× × ÓÖ Ø Ñ ± ± ר ÖØ ÓÖÑ Ø Ø ÓÒ Ø ¸ Ø Ñ ± Ô Ð Ð ÓÖ Ø Ñ × Ö ÔØ ÓÒ × Ö ÔØ ÓÒ »Ð Ð Ö ± Ø ÜØ Ö Ø Ñ ¸ × Ö ÔØ ÓÒ ¸ ÖÓÛ× ± »Ô Ô Ð Ð ÓÖ Ø Ñ ÓÒ ÓÒ »Ð Ð Ö ± × Ð Ø Ø Ñ ¸ ÓÒ ¸ ÆÓ ¸ Ð× ℄¸ × ¸ ØÖÙ ℄℄ ± »Ô Ô Ð Ð ÓÖ Ø Ñ ÓÒØ ÜØ ÓÒØ ÜØ »Ð Ð Ö ± × Ð Ø Ø Ñ ¸ ÓÒØ ÜØ ¸ ÓÒØ ܨ׏ ÔÖÓÑÔØ ¹¹ ÓÓ× ¹¹ ± »Ô Ô Ð Ð ÓÖ Ø Ñ ÔÖÓ Ø ÈÖÓ Ø »Ð Ð Ö ± × Ð Ø Ø Ñ ¸ ÔÖÓ Ø ¸ ÔÖÓ Ø×¸ ÔÖÓÑÔØ ¹¹ ÓÓ× ¹¹ ± »Ô Ô ± ×Ù Ñ Ø Ø Ë Ú ± ÓÖ ± Ð Ò ØÓ Ò Ð ¸ Ø ÓÒ Ð ×Ø ± »Ô ± Ò ÓÖÑ Ø ± Esse é um caso raro, mas se você vir algum erro misterioso acontecendo do Rails onde tudo deveria estar funcionando, verifique se não há um conflito. Como um detalhe extra, invertemos acima a ordem do Yes e No na seleção da situação ativa para o correto que seriam uma ação ainda não concluída por padrão. Rodando agora a ação, 110
  • 112. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF temos o resultado desejado. Vamos agora modificar o controller mais uma vez em apoio à view de listagem dos dados. Teríamos o seguinte: Ð ×× Ø ÓÒ× ÓÒØÖÓÐÐ Ö ÔÔÐ Ø ÓÒ ÓÒØÖÓÐÐ Ö Ò Ü Ð ×Ø Ö Ò Ö Ø ÓÒ Ð ×Ø Ò Ð ×Ø Ø ÓÒ Ô ×¸ Ø ÓÒ× Ô Ò Ø Ø ÓÒ׸ Ò ÐÙ ÔÖÓ Ø¸ ÓÒØ ÜØ℄¸ Ô Ö Ô ¸ ÓÖ Ö Ø ÓÒ׺ × Ö ÔØ ÓÒ Ò Ø ÓÒØ ÜØ× ÓÒØ ÜØº Ò ´ Ðи ÓÖ Ö Ò Ñ µº ÓÐÐ Ø ß ºÒ Ñ ¸ º ℄ ÔÖÓ Ø× ÈÖÓ Øº Ò ´ Ðи ÓÖ Ö Ò Ñ µº ÓÐÐ Ø ß ºÒ Ñ ¸ º ℄ Ô Ö Ñ× ℄ Ø Ñ Ø ÓÒº Ò ´Ô Ö Ñ× ℄µ Ð× Ø Ñ Ø ÓÒºÒ Û Ò Ö ÕÙ ×ØºÔÓר Ø Ñº ØØÖ ÙØ × Ô Ö Ñ× Ø Ñ℄ Ø Ñº× Ú Ð × ÒÓØ ℄ Ì Ø ÓÒ Û × ×Ù ×× ÙÐÐÝ × Ú Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò Ò Ð Ø Ø ÓÒº Ò ´Ô Ö Ñ× ℄µº רÖÓÝ Ð × ÒÓØ ℄ Ì Ø ÓÒ Û × ×Ù ×× ÙÐÐÝ Ð Ø Ö Ö Ø ØÓ Ø ÓÒ Ð ×Ø Ò Ò A inclusão dos relacionamentos irá melhorar a nossa view. Veja que precisamos agora espe- cificar a condição de ordenação mais claramente, já que temos uma coluna chamada description em duas tabelas. Nossa view ficaria assim: ½ Ø ÓÒ× » ½ ± Ð × ÒÓØ ℄ ± Ô ×ØÝÐ ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð ± Ð × ÒÓØ ℄ ± »Ô ± Ò ± Ô ± Ð Ò ØÓ Æ Û Ø ÓÒ ¸ Ø ÓÒ Ø ± »Ô Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø × Ö ÔØ ÓÒ »Ø 111
  • 113. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Ø ÓÑÔÐ Ø »Ø Ø ÈÖÓ Ø »Ø Ø ÓÒØ ÜØ »Ø Ø Ø ÓÒ× »Ø »ØÖ ± Ø ÓÒ׺ Ó Ø ÓÒ ± ØÖ Ø ± Ø ÓÒº × Ö ÔØ ÓÒ ± »Ø Ø ± Ý × ÓÖ ÒÓ ´ Ø ÓÒº ÓÒ µ ± »Ø Ø ± Ø ÓÒºÔÖÓ ØºÒ Ñ ± »Ø Ø ± Ø ÓÒº ÓÒØ ÜØºÒ Ñ ± »Ø Ø ± Ð Ò ØÓ Ø ¸ Ø ÓÒ Ø ¸ Ø ÓÒ ± ÓÖ ± Ð Ò ØÓ Ð Ø ¸ ß Ø ÓÒ Ð Ø ¸ Ø ÓÒ ¸ ÓÒ ÖÑ Ö ÝÓÙ ×ÙÖ »Ø »ØÖ ± Ò ± »Ø Ð Ô ± Ô Ò Ø ÓÒ Ð Ò ×´ Ø ÓÒ Ô ×µ ± »Ô Dando o seguinte resultado: 112
  • 114. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 36 Se quisermos, podemos também acrescentar um campo informando quando a ação foi com- pletada, formatando a data em que a mesma foi completada da maneira necessária à nossa aplicação, ou exibindo um marcador caso contrário. Nossa view poderia ficar como algo assim: ½ Ø ÓÒ× » ½ ± Ð × ÒÓØ ℄ ± Ô ×ØÝÐ ÓÐÓÖ Ö Ò ÓÒØ¹×ØÝÐ Ø Ð ± Ð × ÒÓØ ℄ ± »Ô ± Ò ± Ô ± Ð Ò ØÓ Æ Û Ø ÓÒ ¸ Ø ÓÒ Ø ± »Ô Ø Ð ÓÖ Ö ½ ÐÐÔ Ò ÐÐ×Ô Ò ½ ØÖ Ø × Ö ÔØ ÓÒ »Ø Ø ÓÑÔÐ Ø »Ø Ø Ï Ò »Ø Ø ÈÖÓ Ø »Ø Ø ÓÒØ ÜØ »Ø Ø Ø ÓÒ× »Ø »ØÖ ± Ø ÓÒ׺ Ó Ø ÓÒ ± ØÖ Ø ± Ø ÓÒº × Ö ÔØ ÓÒ ± »Ø Ø ± Ý × ÓÖ ÒÓ ´ Ø ÓÒº ÓÒ µ ± »Ø Ø ± ´ Ø ÓÒº ÓÒ µ Ø ÓÒº ÓÑÔÐ Ø Øº×ØÖ Ø Ñ ´ ±Ñ»± »±Ý µ ¹ ± »Ø Ø ± Ø ÓÒºÔÖÓ ØºÒ Ñ ± »Ø Ø ± Ø ÓÒº ÓÒØ ÜØºÒ Ñ ± »Ø Ø ± Ð Ò ØÓ Ø ¸ Ø ÓÒ Ø ¸ Ø ÓÒ ± ÓÖ ± Ð Ò ØÓ Ð Ø ¸ ß Ø ÓÒ Ð Ø ¸ Ø ÓÒ ¸ ÓÒ ÖÑ Ö ÝÓÙ ×ÙÖ »Ø »ØÖ ± Ò ± »Ø Ð Ô ± Ô Ò Ø ÓÒ Ð Ò ×´ Ø ÓÒ Ô ×µ ± »Ô Com o seguinte resultado: 113
  • 115. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Figura 37 114
  • 116. Capítulo 12 Has many, has one, has many through Além do relacionamento belongs_to, o Rails também possui um outro relacionamento cha- mado has_many, has one, e has many, through. Essa lição visa explicar cada um deles. 12.1 Has many Como o próprio nome indica, esse relacionamento diz que um modelo possui muitos de outros modelos. Em nossa aplicação, nos temos duas instâncias imediatas disso: um contexto possui muitas ações e um projeto possui muitas ações. Modificando inicialmente o modelo de contextos, teríamos: Ð ×× ÓÒØ ÜØ Ø Ú Ê ÓÖ × Ú Ð Ø × ÔÖ × Ò Ó Ò Ñ Ú Ð Ø × ÙÒ ÕÙ Ò ×× Ó Ò Ñ ¸ Ñ ×× ÑÙר ÙÒ ÕÙ × Ñ ÒÝ Ø ÓÒ× Ò Isso é suficiente para estabelecer uma série de métodos adicionais que permitem que você manipule as ações relacionadas a um contexto. Usando o console, podemos ver algumas delas: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» ÓÒ×ÓÐ ÄÓ Ò Ú ÐÓÔÑ ÒØ ÒÚ ÖÓÒÑ ÒØº ÓÒØ ÜØ ÓÒØ ÜØº Ò ´½µ ÓÒØ ÜØ ¼Ü ¿ ½ ØØÖ ÙØ × ß Ò Ñ ÀÓÑ ¸ ½ ÓÒØ ÜØº Ø ÓÒ׺ ÓÙÒØ ½ ÓÒØ ÜØº Ø ÓÒ× Ø ÓÒ ¼Ü ¿ ¾ ØØÖ ÙØ × ß ÓÒØ ÜØ ½ ¸ ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ Ø ¿ ÓÒ ¼ ¸ ¸ × Ö ÔØ ÓÒ Ë Ø ÓÛÒ Ò ÛÖ Ø ¸ Ú ÖÝ Ý¸ Ø Ð ×Ø ØÛÓ ÓÙÖ× Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¿½ ½ ℄ Se criarmos mais uma ação associada a esse contexto, teríamos algo assim: Ø ÓÒ Ø ÓÒº Ö Ø ´ × Ö ÔØ ÓÒ ÙÝ Ö ÑÑ Ö ØÓ ÐÔ Ñ Û Ø ÑÝ Ò Ð × º ¸ ÓÒØ ½¸ ÔÖÓ Ø ¿µ Ø ÓÒ ¼Ü Ò Û Ö ÓÖ Ð× ¸ ÖÖÓÖ× Ø Ú Ê ÓÖ ÖÖÓÖ× ¼Ü 115
  • 117. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF × Ø ÓÒ ¼Ü ººº ¸ ÖÖÓÖ× ß ¸ ØØÖ ÙØ × ß ÓÒØ ÜØ ½¸ ÓÑÔÐ Ø Ø Ò ÔÖÓ Ø ¿¸ ÓÒ Ò Ð¸ ½½¸ × Ö ÔØ ÓÒ ÙÝ Ö ÑÑ Ö ØÓ ÐÔ Ñ Û Ø ÑÝ Ò Ð Ö Ø Ø Ì Ù Ë Ô ¾½ ½ ¾ ¼ ÊÌ ¾¼¼ ÓÒØ ÜØº Ø ÓÒ× Ø ÓÒ ¼Ü ¿ ¾ ØØÖ ÙØ × ß ÓÒØ ÜØ ½ ¸ ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ Ø ¿ ÓÒ ¼ ¸ ¸ × Ö ÔØ ÓÒ Ë Ø ÓÛÒ Ò ÛÖ Ø ¸ Ú ÖÝ Ý¸ Ø Ð ×Ø ØÛÓ ÓÙÖ× Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¿½ ½ ℄ ÓÒØ ÜØº Ø ÓÒ×ºÖ ÐÓ Ø ÓÒ ¼Ü ØØÖ ÙØ × ß ÓÒØ ÜØ ½ ¸ ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ Ø ¿ ÓÒ ¼ ¸ ¸ × Ö ÔØ ÓÒ Ë Ø ÓÛÒ Ò ÛÖ Ø ¸ Ú ÖÝ Ý¸ Ø Ð ×Ø ØÛÓ ÓÙÖ× Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¿½ ½ ¸ Ø ÓÒ ¼Ü ¼ ØØÖ ÙØ × ß ÓÒØ ÜØ ½ ¸ ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ Ø ¿ ¸ ÓÒ Ò Ð¸ ½½ ¸ × Ö ÔØ ÓÒ ÙÝ Ö ÑÑ ÐÔ Ñ Û Ø ÑÝ Ò Ð × º ¸ Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¾ ¼ ℄ ÓÒØ ÜØº Ø ÓÒ׺ ÓÙÒØ ¾ ÓÒØ ÜØº Ø ÓÒ׺ ÑÔØÝ Ð× Note que, como usando um objeto já carregado, a coleção de ações não foi recarregada depois que uma nova ação foi adicionada. Isso acontece porque o Rails faz um cache de coleções e a ação foi adicionada através de seu próprio constructor e não usando os métodos da coleção. O método reload pode ser usado para recarregar a coleção caso você precise. Um outro exemplo seria: ÓÒØ ÜØº Ø ÓÒ× Ø ÓÒº Ö Ø ´ × Ö ÔØ ÓÒ ÍÔ Ö ÑÝ ÛÓÖ ÔÖÓ ××ÓÖº ¸ ÔÖÓ Ø Ø ÓÒ ¼Ü ØØÖ ÙØ × ß ÓÒØ ÜØ ½ ¸ ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ Ø ¿ ÓÒ ¼ ¸ ¸ × Ö ÔØ ÓÒ Ë Ø ÓÛÒ Ò ÛÖ Ø ¸ Ú ÖÝ Ý¸ Ø Ð ×Ø ØÛÓ ÓÙÖ× Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¿½ ½ ¸ Ø ÓÒ ¼Ü ¼ ØØÖ ÙØ × ß ÓÒØ ÜØ ½ ¸ ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ Ø ¿ ¸ ÓÒ Ò Ð¸ ½½ ¸ × Ö ÔØ ÓÒ ÙÝ Ö ÑÑ ÐÔ Ñ Û Ø ÑÝ Ò Ð × º ¸ Ö Ø Ø ¾¼¼ ¹¼ ¹¾½ ½ ¾ ¼ ¸ Ø ÓÒ ¼Ü ¿½ ¼ Ò Û Ö ÓÖ Ð× ¸ ÖÖÓÖ× Ø Ú Ê ÓÖ ÖÖÓÖ× ¼Ü ½¿ ¼ × Ø ÓÒ ¼Ü ¿½ ¼ ººº ¸ ÖÖÓÖ× ß ¸ ØØÖ ÙØ × ß ÓÒØ ÜØ ½¸ ÓÑÔÐ Ø Ø Ò Ð¸ ÔÖÓ Ø ¿¸ ÓÒ Ò Ð¸ ½¾¸ × Ö ÔØ ÓÒ ÍÔ Ö ÑÝ ÛÓÖ ÔÖÓ ××ÓÖº ¸ Ö Ø Ø Ì Ù Ë Ô ¾½ ½ ¾½ ÊÌ ÓÒØ ÜØº Ø ÓÒ×º× Þ ¿ Nesse caso, você pode ver que duas coisas aconteceram: primeiro, não foi necessário in- formar o contexto, que é pego automaticamente no objeto; segundo: a coleção cresceu auto- maticamente, já que estamos manipulando os dados diretamente na mesma. Ao invés de usar os métodos acima para criar a ação, você pode usar diretamente os métodos build e create na coleção para adicionar novos dados. O primeiro funciona para objetos já existentes na coleção e o segundo para adicionar um novo objeto. Uma coleção também possui um método find para encontrar objetos dentro da mesma, de acordo com as mesmas regras do método find usado para classes de dados. Por fim, por razões de eficiência, toda coleção declara um método do objeto pai para atribuição rápida de valores. No caso do objeto acima, o método é chamada action_ids e pode ser usado para trocar completamente os dados de uma coleção. Por exemplo: ÓÒØ ÜØº Ø ÓÒ × ½¸ ¾¸ ℄ 116
  • 118. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Isso removeria qualquer ação associada àquele contexto, substituindo-as pelas ações identi- ficadas pelos ids acima. A coleção toda pode ser substituída com objetos também, como mostrado abaixo: ÓÒØ ÜØº Ø ÓÒ× Ø ÓÒº Ò ´ Ðи ÓÒ Ø ÓÒ× ÔÖÓ Ø ¸ ℄µ O contexto acima teria todas as suas ações substituídas pelas ações associadas ao projeto cujo id é 5. Investigando a documentação você poderá encontrar mais detalhes sobre como cada método funciona. Um exemplo disso é a destruição automática de registros quando um registro pai for excluído. Isso pode fazer um objeto ter a funcionalidade equivalente de uma declaração cascade em um banco de dados. Uma coisa que deve ser notada é que muitos desse métodos causam o salvamento imediato dos dados (se o objeto pai já está salvo). Com a prática, você será capaz de identificar quais são esses métodos e agir apropriadamente caso queria outra ação, embora o comportamento padrão seja o desejado na maior parte dos casos. Não vamos utilizar esses métodos em nossa aplicação no momento porque veremos uma aplicação similar mais à frente com outro tipo de relacionamento parecido. 12.2 Has one Dois outros relacionamentos existentes no Rails são has_and_belongs_to_many e has_one. O relacionamento has_one geralmente expressa o oposto do relacionamento belongs_to. Por exemplo, digamos que temos duas tabelas: uma contendo cartões de crédito e outra contendo o titulares de cartões. Na tabela de cartão de crédito teríamos uma chave estrangeira apontando para o seu titular. Teríamos então as seguintes classes: Ð ×× Ö Ø Ö Ø Ú Ê ÓÖ × ÐÓÒ × ØÓ ÓÙÒØ ÓÐ Ö Ò Ð ×× ÓÙÒØÀÓÐ Ö Ø Ú Ê ÓÖ × × ÓÒ Ö Ø Ö Ò A diferença é que a chave estrangeira existe somente na tabela relacionada à classe Credit- Card, sendo automaticamente deduzida no relacionamento inverso. Esse exemplo não é muito bom já que, em tese, uma pessoa poderia ter vários cartões de crédito. Mas a idéia é essa. Na prática, esse tipo de relacionamento é mais raro e geralmente tende a se transformar em relacionamentos do tipo has_many ou has_many_and_belongs_to. O relacionamento has_many_and_belongs_to, por sua vez, representa a intermediação entre duas tabelas. Por exemplo, a relação entre desenvolvedores e projetos em uma empresa. Um desenvol- vedor pode estar locado em múltiplos projetos e um projeto pode ter múltiplos desenvolvedores. Veremos mais detalhes desse relacionamento adiante quando fizermos mais modificações em nossa aplicação para suportar outras características. 117
  • 119. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF 12.3 Has many, trough Um tipo interessante de relacionamento, introduzido no Rails 1.1, é aquele relacionamento em que uma tabela intermediária é usada para colapsar outra. Digamos, por exemplo, que você tenha modelos representando empresas, clientes e notas ficais e você queira descobrir todas as notas fiscais emitidas por um empresa qualquer. É aqui que esse tipo de relacionamento entra em ação, permitindo que o código seja simplificado. Vamos experimentar um pouco, usando o console. Digamos que você queria, em nossa aplicação, saber todos os contextos associados a um projeto. A maneira simples seria fazer isso: ÖÓÒ Ð ÓÑ Ò ÖÚ »ØÑÔ» Ø ° × Ö ÔØ» ÓÒ×ÓÐ ÄÓ Ò Ú ÐÓÔÑ ÒØ ÒÚ ÖÓÒÑ ÒØº ÔÖÓ Ø ÈÖÓ Øº Ò ´¿µ ÈÖÓ Ø ¼Ü ¼ ¿ ØØÖ ÙØ × ß Ò Ñ ÏÖ Ø ÓÓ ¸ ¿ ¸ × Ö ÔØ ÓÒ ¸ Ø Ú ½ ÔÖÓ Øº Ø ÓÒ׺ ÓÐÐ Ø ß º ÓÒØ ÜØºÒ Ñ ÀÓÑ ¸ ÀÓÑ ¸ ÀÓÑ ℄ Como você pode ver, o contexto é o mesmo para todas as ações associadas àquele projeto e queremos os contextos sem repetição. Uma solução simples seria: ÓÒØ ÜØ× ÔÖÓ Øº Ø ÓÒ׺ ÓÐÐ Ø ß º ÓÒØ ÜØºÒ Ñ ÀÓÑ ¸ ÀÓÑ ¸ ÀÓÑ ℄ ÓÒØ ÜØ×ºÙÒ Õ ÀÓÑ ℄ O problema é que, além de usar mais código, essa solução é muito ineficiente por causa das comparações que precisam ser realizadas pelo método uniq. Podemos resolver o problema usando então a seguinte estratégia: Ð ×× ÈÖÓ Ø Ø Ú Ê ÓÖ × Ú Ð Ø × ÔÖ × Ò Ó Ò Ñ Ú Ð Ø × ÙÒ ÕÙ Ò ×× Ó Ò Ñ × Ñ ÒÝ Ø ÓÒ× × Ñ ÒÝ ÓÒØ ܨ׏ Ø ÖÓÙ Ø ÓÒ׸ × Ð Ø ×Ø Ò Ø ÓÒØ ÜØ×º¶ Ò Usando esse método tempos: ÔÖÓ Øº ÓÒØ ÜØ×º ÓÐÐ Ø ß ºÒ Ñ ÀÓÑ ℄ Como você pode ver, muito mais fácil e interessante e, em quase todos os casos, mais efici- ente. No relacionamento acima, temos os contextos de um projecto obtidos através (through) de suas ações. Se não for necessário preocupar com cópias (como no exemplo das notas fiscais) poderemos inclusive descartar o parâmetro select que é um fragmento de SQL usado no lugar do gerado automaticamente pelo Rails. 118
  • 120. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasília/DF Associações through são muito poderosas e podem ser utilizadas em várias situações para agilizar o código e melhorar a legibilidade da aplicação. Com isso, chegamos ao fim do nosso curso do básico de Ruby on Rails. Espero que venha a ser útil para vocês. 119