Entendendo Rails

Preview:

DESCRIPTION

Entendendo Rails. Fabio Akita Surgeworks Brazil Rails Practice Manager www.akitaonrails.com. 37signals. Criado por David Heinemeier Hansson, em 2004 Extraído do aplicativo Basecamp Feito em Ruby, em vez de PHP ou Java Lançamento da versão 1.0 em dez/2005. O que é Rails?. - PowerPoint PPT Presentation

Citation preview

Entendendo Rails

Fabio Akita

Surgeworks Brazil Rails Practice Manager

www.akitaonrails.com

37signals

• Criado por David Heinemeier Hansson, em 2004

• Extraído do aplicativo Basecamp

• Feito em Ruby, em vez de PHP ou Java

• Lançamento da versão 1.0 em dez/2005

O que é Rails?• “full stack web framework”

• Framework completo para desenvolvimento de aplicativo Web

• Pacote MVC (Model-View-Controller)– Action Pack (Action Controller e Action View)– Active Record

• Suporte a envio e recebimento de e-mails– Action Mailer

• Suporte a Web Services– Action WebServices

Arquitetura Rails

Por que Ruby?

• Linguagem Dinâmica• Fortemente Tipada• Muito Expressiva• Altamente Produtiva• Totalmente Orientado a Objetos• Herança de SmallTalk e Lisp• Simples sem ser complexa• Sintaxe familiar e coerente• Permite criação de Linguagem

Específica de Domínio (DSL)

Começo Simples

• Windows: Instant Rails– wiki.rubyonrails.com/rails/pages/InstantRails

• Mac e Linux: – FiveRuns RB-Install

• www.fiveruns.com/products/rm/install

Começo Padrão

• Instalar Ruby 1.8.6– www.ruby-lang.org/en/downloads

• Instalar RubyGems (Mac ou Linux)– rubyforge.org/frs/?group_id=126

• Instalar Rails (linha de comando)– gem install rails

• Instalar MySQL (suporta outros bancos)– dev.mysql.com/downloads

Primeiro Passo

• Saber o que queremos:

– David Hansson tem um screencast demonstrando a criação de um pequeno blog em 15 minutos

– http://media.rubyonrails.org/video/rails_take2_with_sound.mov

• Queremos um blog semelhante

O Que temos no Blog?

• Uma tabela de Posts• Uma tabela associada de Comments• Uma tela de listagem de Posts• Uma tela de criação e edição de Posts• Uma tela de detalhes do Post• No detalhe do Post vemos e adicionamos

Comments

• Faremos tudo em inglês. Não é difícil adaptar para Português, mas não é escopo desta demonstração

Novo Projeto

• rails <projeto>

Novo Banco de Dados

• create database <projeto>_<ambiente>

Ambientes

• Rails vem preparado para lidar com três ambientes diferentes:

– Development (sandbox)

– Test (testes unitários, funcionais, integrados)

– Production (produção)

Convenção sobre Configuração

• Estrutura comum de diretórios

Configuração Mínima

• Banco de dados

• No exemplo, apenas colocando as senhas

Criando um Controller

• script/generate controller <nome>

Controllers e Actions

• Todo Controller fica no diretório:– /app/controllers/<nome>_controller.rb

• Todo Controller herda a classe ApplicationController

• Todo aplicativo Rails é criado com uma classe chamada ApplicationController, que herda de ActionController::Base, e é base de todos os outros controllers

• Todo método de um controller é chamado de Action

Criando uma Action

• Uma classe Controller pode ter quantas Actions quanto necessárias

Servidor de Teste: WEBRick

Roteamento Customizável

• http://localhost:3000/:controller/:action/:id

Acessando uma Action

• Seguindo a regra anterior de roteamento– http://localhost:3000/blog/index

– blog = app/controller/blog_controller.rb– index = método index em BlogController

Criando uma View

Mais Convenções

• Ao final de toda Action, Rails chamará uma view com o mesmo nome da Action, no seguinte diretório:– /app/views/<controller>/<action>.<ext>

• A extensão do arquivo pode ser:

– .rhtml - Embedded Ruby (HTML+Ruby)– .rxml - XML Builder (Ruby puro)– .rjs - Javascript Generator (Ruby puro)

• Este fluxo pode ser interrompido com uma chamada explícita ao método render ou redirect_to

Implementando Post

• script/generate model <nome>

Migration

• Manutenção de tabelas usando Ruby

• Independente de banco

• Mas também suporta SQL nativo

Rake: Ruby Make

• Execução de tarefas, implementadas em Ruby

• Primeira tarefa: manutenção das tabelas

rake migrate• Toda entidade criada com script/generate gera um

arquivo de Migration no diretório db/migrate

• Todo arquivo Migration é numerado:– 001_create_posts.rb

• O comando rake migrate executa os arquivos em db/migrate

• Usa a tabela schema_info no banco de dados para saber a partir de qual numeração começar

• O gerenciamento do banco de dados é feito totalmente em Ruby

Mapeando Tabelas• A classe Post já é capaz de gerenciar os dados da tabela no banco de dados

• Não há necessidade de explicitar o mapeamento das colunas do banco com atributos da classe

• Rails não proíbe nada: se for necessário existe como mapear uma coluna para outro atributo de nome diferente

Convenções de Entidades• Toda entidade é criada no diretório padrão:

– /app/models/<controller>/<model>.rb

• Toda entidade herda diretamente da classe ActiveRecord::Base

• Não há necessidade de mapear manualmente cada coluna da tabela

• Convenção: a classe tem o nome no singular (Post), a tabela tem o nome do plural (posts)

• Convenção: Surrogate Key, toda tabela tem uma chave primária chamada “id” que é um número auto-incrementável

annotate_models

annotate_models

• Plugin de Dave Thomas

• Instalação (via internet):– script/plugin install annotate_models

• Utilização (via rake):– rake annotate_models

• Lê a tabela do banco de dados e coloca um cabeçalho como comentário na classe entidade

Scaffold

Scaffold

• Colocar o método scaffold :<model> no controller é suficiente

• Telas CRUD (Create, Read, Update, Delete) geradas automaticamente em tempo de execução (runtime)

• CUIDADO: Rails NÃO é Scaffold

• Scaffold é apenas uma pequena funcionalidade para facilitar prototipação

Configurando Post

• Acrescentando validação

Testando modificação

• Não é necessário reiniciar servidor

Incrementando Post

• Criando novas colunas com Migration• script/generate migration <atividade>

Executando Migration

Criando um Post

• Novamente, sem reiniciar o servidor

Gerando o Scaffold

• script/generate scaffold <model> <controller>

Arquivos Gerados

• Toda execução automática de antes agora está exposta em arquivos que podemos editar como quisermos

• Provado: Rails não se restringe a Scaffold automático

Modificando a Listagem

• /app/views/blog/list.rhtml

Testando a listagem

• http://localhost:3000/blog

• Portanto, podemos alterar o layout ou qualquer código como quisermos

Polêmica do Scriplet

• Rails não utiliza taglibs

• Ruby é simples e expressiva o suficiente para não precisar de artifícios

• Taglibs são simplificações de lógica

• Podemos fazer tudo de maneira simples e flexível sem precisar aprender sintaxes complexas de XML

ExemplosTaglibs

<logic:iterate id=”post" collection="<%=posts%>">

Faz alguma coisa com post

</logic:iterate>

<logic:equal parameter="number" value="7">

Está correto!

</logic:equal>

Scriptlets

<% @posts.each do |post| %>Faz alguma coisa com post<% end %>

<% if number == "7" %>Está correto!

<% end %>

Portanto, é a mesma coisa !

Criar Comment

• Hora de criar a entidade Comment

• Lembrete: esta entidade será associada a um Post

Rake outra vez• Obs: Comment pertence a Post através da coluna post_id.

• Convenção de Chave Estrangeira: <classe>_id

Associações

Usando associações

• Criando formulário de Comment na tela de detalhe de um Post– /app/views/blog/show.rhtml

Partials• “Don’t Repeat Yourself” (DRY)

• Uma das maneiras de separar trechos de código

• Toda partial começa com underline “_”

– <%= render :partial => "comment", :collection => @post.comments %>

• Associação has_many em Post automaticamente fornece um hash chamado comments (nome da outra entidade no plural)

Action para Comment• <% form_for :comment, @comment, :url => {:action => 'add_comment', :id

=> @post } do |f| %>

– Action esperada: add_comment

– Passando parâmetros: params[:id] e params[:comment]

– Hash params[:comment] contém todos os campos do formulário enviado.

Resultado Final

• Tela de Post com a lista de Comments

Layouts• Todo novo controller automaticamente ganha um layout no diretório:

– /app/views/layouts/<controller>.rhtml

– As views desse controller preenchem o espaço:• <%= @content_for_layout %>

Testes Unitários• Toda nova entidade ganha um arquivo para teste unitário em:

– /app/test/unit/<entidade>_test.rb

• Devemos seguir os preceitos de Test-Driven Development:

– “Se não vale a pena testar, para que estamos codificando?”

Ambiente de Teste

• Os testes acontecem em banco de dados separado do desenvolvimento– <projeto>_test

• Cada teste roda de maneira isolada: os dados modificados em um teste não afetam outro teste

• Cada teste unitário tem um arquivo de “fixture”, carga de dados para testes:– /app/test/fixture/<tabela>.yml

Fixture YAML

• “YAML Ain’t a Markup Language”

• Maneira de serializar objetos Ruby em forma de texto

• Formato humanamente legível

• Mais leve e simples que XML

Rodando Testes Unitários

• Todos os testes unitários– rake test:units

• Apenas um teste unitário:– ruby test/unit/<entidade>_test.rb

Testes Funcionais• Todo novo controller ganha uma classe de teste em:

– /app/test/functional/<classe>_controller_test.rb

• Devemos testar cada action do controller

• Métodos como get e post simulam navegação com um browser

Rodando Testes Funcionais

• Todos os testes funcionais:– rake test:functionals

• Apenas um testes funcional:– ruby test/functional/<classe>_controller_test.rb

Mais Testes

• Testes Unitários devem testar todos os aspectos da entidade como associações, validações, callbacks, etc

• Testes Funcionais devem testar todas as actions de um mesmo controller, todos os fluxos, redirecionamentos, filtros, etc

• Testes Integrados servem para avaliar a navegação e fluxos entre actions de diferentes controllers. Funcionam de maneira semelhante a um teste funcional

Ajax

• Rails é o melhor modelo de framework para Ajax

• Ajax é codificado em Ruby puro• Integração com as bibliotecas Prototype e

Script.aculo.us

• Ajax representa um passo em direção a um “Aplicativo” Web– Sem necessidade de recarregar a página toda a

cada ação– Capacidade de atualizar apenas trechos da tela– Capacidade de realizar um post (submit) sem sair da

página– Capacidade de receber apenas a informação que

precisa ser atualizada em vez de receber a página inteira

View Ajaxfied

• Maneira simples: apenas trocar form_for para remote_form_for

Action Ajaxfied• request.xhr? checa se veio chamada via Ajax. Caso contrário

redireciona para a mesma action de antes, que retorna a página toda

• Desta vez guardamos o novo comment na variável de instância @comment

Arma Secreta: RJS

• Mesma convenção: action add_comment espera encontrar a página – /app/views/blog/add_comment.rjs

Ativando Ajax

• Ativado por controller, através de seu layout com o método javascript_include_tag

Testando Ajax• Na foto de tela não podemos mostrar o efeito.

• Recomendamos testar ao vivo. As possibilidades são enormes!

Active Record Interativo• script/console

• Toda entidade criada pode ser manipulada pelo console

• Facilita testes antes de criar as actions

Produto Final

• Mini Blog criado conforme requerimentos iniciais (slide 9)

• Plus: pequeno brinde via Ajax

• Conseguimos criar entidades e tabelas sem mapear campo-a-campo manualmente– deixe o computador trabalhar por nós

• Infraestrutura completa de testes unitários, funcionais e integrados

• Obs: este é um aplicativo de demonstração, muito mais ainda pode ser feito !

O que NÃO fizemos• Não precisamos recompilar e reinstalar o aplicativo a cada mudança

• Não precisamos reiniciar o servidor a cada mudança

• Não precisamos mapear cada uma das colunas das tabelas para as entidades

• Não precisamos configurar dezenas de arquivos XML. Basicamente colocamos a senha do banco de dados, apenas

• Não precisamos usar Javascript para fazer Ajax: a maior parte pode ser feita com Ruby puro

• Não sentimos falta de taglibs: expressões Ruby, partials foram simples o suficiente

• Não precisamos codificar código-cola, o framework possui “padrões espertos” afinal, todo aplicativo Web tem a mesma infraestrutura

Linhas de Código

• Estatística polêmica mas relevante• Ruby on Rails permite fazer muito mais com

muito menos

Próximos Passos

• Aprender mais!

– Programming Ruby (livro gratuito! Em inglês)– http://www.rubycentral.com/book/intro.html

– Agile Web Development With Rails (livro mais famoso de Rails, em inglês)

– http://www.pragmaticprogrammer.com/titles/rails2/

– Melhores websites sobre Ruby e Rails– http://del.icio.us/fabioakita/rubyonrails

– Akita On Rails: principal site de Rails do Brasil– http://www.akitaonrails.com

… e TAMBÉM• Repensando a Web com Rails

– Primeiro livro de Ruby on Rails em português no Brasil

– Documentação completa do Rails versão 1.1.2

– Cada um dos tópicos desta demonstração em detalhes

– Por Fabio Akita (www.balanceonrails.com.br)• Consultor SAP há 5 anos• Gerente de Projetos PMP• Desenvolvedor Java há 8 anos• Utilizando diversas plataformas de desenvolvimento há

14 anos

– Pela editora Brasport, já disponível!

DúvidasSugestões

Críticas

• Participe de nosso grupo – akitaonrails@googlegroups.com

• Podem me escrever diretamente– fabioakita@gmail.com