• Nenhum resultado encontrado

CENTRO UNIVERSITÁRIO METODISTA BENNETT. Rafael Gomes de Oliveira Polo Sabrina Arêas DESENVOLVIMENTO ÁGIL DE SISTEMAS PARA A WEB 2.

N/A
N/A
Protected

Academic year: 2021

Share "CENTRO UNIVERSITÁRIO METODISTA BENNETT. Rafael Gomes de Oliveira Polo Sabrina Arêas DESENVOLVIMENTO ÁGIL DE SISTEMAS PARA A WEB 2."

Copied!
52
0
0

Texto

(1)

CENTRO UNIVERSITÁRIO METODISTA BENNETT

Rafael Gomes de Oliveira Polo Sabrina Arêas

(2)

CENTRO UNIVERSITÁRIO METODISTA BENNETT

Rafael Gomes de Oliveira Polo Sabrina Arêas

DESENVOLVIMENTO ÁGIL DE SISTEMAS PARA A WEB 2.0 COM RAILS

Monografia apresentada ao Centro Universitário Metodista Bennett, como parte dos requisitos para obtenção do título de Bacharel em Ciência da Computação.

Orientador: Prof. Sávio Figueiredo

Rio de Janeiro Novembro, 2009

(3)

CENTRO UNIVERSITÁRIO METODISTA BENNETT

Rafael Gomes de Oliveira Polo Sabrina Arêas

Orientador: Prof. Sávio Figueiredo

DESENVOLVIMENTO ÁGIL DE SISTEMAS PARA A WEB 2.0 COM RAILS

Trabalho de Conclusão do Curso de Ciência da Computação do Centro Universitário Metodista Bennett como parte dos requisitos necessários à obtenção do título de Bacharel em Ciência da Computação.

Aprovado por:

____________________________________ Prof. Sávio Figueiredo, MSc – Presidente ____________________________________

Prof. Carolina Xavier, MSc

____________________________________ Prof. Vinicius da Fonseca Vieira, MSc

(4)

RESUMO

DESENVOLVIMENTO ÁGIL DE SISTEMAS PARA A WEB 2.0 COM RAILS

Rafael Gomes de Oliveira Polo Sabrina Arêas

Orientador: Prof. Sávio Figueiredo

Este trabalho tem por objetivo apresentar alguns aspectos dos novos princípios de arquitetura de software voltadas para a World Wide Web, mostrando que o refinamento dos novos frameworks para sistemas de informação na Web permitem o desenvolvimento ágil e com qualidade, eliminando tarefas recorrentes nos projetos. Demonstramos essa viabilidade na implementação de dois sistemas Web com um moderno framework.

Palavras-chave: HTTP, WEB 2.0, REST, URI, RUBY ON RAILS

Rio de Janeiro Novembro, 2009

(5)

ABSTRACT

AGILE SYSTEMS DEVELOPMENT FOR WEB 2.0 WITH RAILS

Rafael Gomes de Oliveira Polo Sabrina Arêas

Advisor:

Prof. Sávio Figueiredo

This paper aims to present some aspects of the new principles of software architecture focused on the World Wide Web, showing that the refinement of new information system’s frameworks allows agile development with quality, eliminating recurring tasks in projects. We demonstrates its viability implementing two Web systems with a modern framework.

Key-words: HTTP, WEB 2.0, REST, URI, RUBY ON RAILS

Rio de Janeiro Novembro, 2009

(6)

AGRADECIMENTOS

Agradeço ao meu esposo por sempre me mostrar que posso ir além. Aos meus pais que são responsáveis por eu estar aqui hoje. Ao meu irmão por sempre me levar a busca pela sabedoria e aos Mestres da casa por todo conhecimento transmitido.

(Sabrina)

Agradeço à meus pais e familiares pelo exemplo de determinação e bondade que me faz seguir em frente, a minha irmã pelo incentivo e colaboração, aos amigos pelos momentos de diversão e por manterem minha curiosidade no mundo acesa.

(7)

“A mente que se abre a uma nova idéia jamais voltará ao seu tamanho original.”

(8)

Sumário

1 - Introdução...1

1.1 - Objetivos ...2

1.2 - Justificativa...3

2 - Revisão...5

2.1 - Mapeamento Objeto Relacional ...5

2.1.1 - Active Record...6

2.1.2 - ActiveRecord do Framework Ruby On Rails ...6

2.1.3 - Desvantagens do Active Record ...8

2.2 - Sistema de caching ...9 2.2.1 - Caching on Rails ...10 2.2.2 - Paging Cache ...11 2.2.3 - Action Cache ...11 2.2.4 - Fragment Caching ...11 2.2.5 - Sweepers ...12 2.2.6 - SQL caching ...12

2.2.7 - Conditional GET Support ...12

2.3 – View e Templates ...13 2.3.1 - Partials ...13 2.3.2 - Render ...14 2.3.4 - RHTML...15 2.3.5 - Helpers...16 2.4 - Roteamento de URLs...17

2.4.1 - Conectando URLs com o código ...17

2.4.2 - Gerando URLs do código...17

2.4.3 - Routes.rb...18

2.4.4 - Processando o arquivo ...18

2.4.5 - Rotas RESTful ...19

(9)

2.4.7 - Rotas Aninhadas...20

2.4.8 - Rotas Regulares ...20

2.4.9 - Rotas Padrão ...20

2.4.10 - Roteamento RESTful: o Padrão Rails...20

3 - Estudo de caso...21

3.1 - Estudo de caso - baixogavea.com ...22

3.1.1 – Criação do Projeto...22

3.1.2– Definição do SGBD ...22

3.1.3 – Definição do Schema ...23

3.1.4 – Modelos...25

3.1.5 – Migrando e Testando ...27

3.1.6 – Roteando as requisições HTTP aos controladores...29

3.1.7 - Visualizando as respostas através dos templates ...35

3.1.8 - AJAX ...36

4- Resultados e Conclusões...38

4.1 – Trabalhos Futuros ...40

(10)

1 - Introdução

Desde a crise do software nos anos 70 - ano de desenvolvimento e comercialização do microprocessador - quando a demanda por sistemas de informação era progressiva, boa parte dos projetos estourava o orçamento e o prazo e softwares tinham baixa qualidade ou se tornavam muito complexos para serem gerenciados, o uso de melhores técnicas, métodos e ferramentas se fez necessário. Muito se evoluiu em pouco mais de 40 anos, desde quando o termo Engenharia de Software foi utilizado oficialmente em 1968 na Conferência sobre Engenharia de Software da OTAN.

A década de 80 viveu a popularização dos Sistemas Operacionais e o uso de PCs (computadores pessoais) para uso não necessariamente empresarial ou científico. No ápice de um contexto histórico, da guerra fria aos movimentos de contra-cultura, essa época é considerada o fim da Sociedade Industrial e o início da Sociedade da Informação, a computação foge do seu único destino de processamento de dados corporativos para tornar-se um instrumento de criação de textos, imagens e música. A informática perde seu status de técnica industrial para fundir-se com as telecomunicações, editoração, digitalização e multimídia.

No começo da década de 90 o cientista da computação Tim Berners Lee publicou seu projeto sobre a World Wide Web (teia de alcance global) e um sistema de identificação global e único de recursos, o Uniform Resource Identifier (URI), além de um servidor de hipertexto e o primeiro browser, desenvolvido na CERN (Organização Europeia para a Investigação Nuclear), o WorldWideWeb, que funda toda a arquitetura de nossa Web contemporânea.

(11)

De forma geral, visualizar uma página web ou outro recurso disponibilizado na rede normalmente inicia ao digitar uma URL (Uniform Resource Locator) no navegador ou seguindo um hiperlink. Primeiramente, a parte da URL referente ao servidor web é separada e transformada em um endereço IP, por um banco de dados da Internet chamado Domain Name System (DNS). O navegador estabelece então uma conexão TCP-IP com o servidor web localizado no endereço IP retornado. Em seguida o navegador envia uma requisição HTTP (Protocolo de Transferência de Hipertexto) ao servidor para obter o recurso indicado pela parte restante da URL. No caso de uma página web típica, o texto HTML é recebido e interpretado pelo navegador, que realiza então requisições adicionais para figuras, arquivos de formatação, arquivos de script e outros recursos que fazem parte da página. O navegador então gera a página na tela do usuário, assim como descrita pelos arquivos que a compõe.

Diversas são as camadas de tecnologias que nos permitem a Internet tal como é hoje. No ano 2000, Roy Fielding, um dos principais autores das especificação do protocolo HTTP, em sua tese de doutoramento (PHD) apresenta a Transferência de Estado Representacional (Representational State Transfer) ou somente REST, uma técnica de engenharia de software para sistemas hipermídia distribuídos, como é a própria World Wide Web. Sistemas RESTful maximizam o uso de interfaces bem definidas pré-existentes e minimizam a necessidade de novas camadas de abstração ao sistema.

1.1 - Objetivos

Sendo notório que cada pedaço de conhecimento deve ter uma representação inequívoca num sistema de informação e que na Web um sistema tende a ser aberto, evolutivo e

(12)

reusado por outros nós da rede, é cada vez mais comum o uso de APIs públicas (Interface de Programação de Aplicativos) por conhecidas organizações como o Flickr, Youtube, Open Social, Facebook, Blogspot, eBay e Twitter que fazem de seu sistema de informação um eco-sistema aberto além de seu domínio. Um nó na rede pode ter seu próprio repositório de vídeos, imagens, microblogging integrado à mapas apenas com

mashups dessas interfaces.

Hoje, a Web vai muito além da simples exibição de páginas, quase duas décadas desde sua invenção, aproximadamente 20% da população mundial usa a Internet para atividades cada vez mais essenciais, países como a Estônia já elegeram seus governantes pela Internet. Como o computador é uma máquina universal, em rede, reinventamos a comunicação, a mídia e as próprias relações humanas. Diversos são os estudos que demonstram a simbiose da tecnologia e a cultura na última década, mas nos limitaremos a analisar e demonstrar o atual estado da arte da ágil construção de sistemas de informação com base no protocolo de transferência de hipertexto, o HTTP, a aquitetura REST e apresentar estudos de caso que desenvolvemos e publicamos na Web, o http://baixogavea.com e o http://mostre.me utilizando um moderno framework publicado inicialmente em 2004, o Ruby on Rails, cujos principais conceitos (mapeamento objeto-relacional, sistema de cache, template e roteamento) faremos uma revisão e apresentaremos como pesquisa dos sistemas desenvolvidos.

1.2 - Justificativa

Nos quatro anos de experiência em desenvolvimento Web vimos diversos frameworks com as mais distintas funções.

(13)

"Framework é um conjunto de classes que colaboram para realizar uma responsabilidade para um domínio de um subsistema da aplicação." - FAYAD e SCHMIDT

Em Java, uma das linguagem mais bem aceitas pelo mercado, conhecemos o Hibernate, o Velocity e o Spring, em Python o Django, adotado como base em muitos serviços do Google, em PHP o CakePHP e em Ruby o Rails, tendo sido esse último escolhido por ser um meta-framework open-source em constante evolução por uma engajada comunidade internacional de desenvolvedores e ter uma ótima documentação - é a junção de quatro frameworks, Active Record, Action Pack, Action Mailer e Active Support.

Além disso, o Rails oferece um inovador roteamento de requisições, um conjunto de utilitários de testes e geração de documentação inspirados em sistemas UNIX em uma bem definida arquitetura MVC (Model-View-Controller), como a figura 1 representa.

(14)

2 - Revisão

O conteúdo e os conceitos necessários para o desenvolvimento de uma aplicação Web completa extrapolam nosso intuito de apresentar as novas abordagens para realizá-las com ganhos significativos em produtividade, portanto resumiremos nossa revisão aos principais conceitos modernos de Mapeamento Objeto Relacional, Sistema de Caching, View e Templates e Roteamento de URLs.

2.1 - Mapeamento Objeto Relacional

Mapeamento objeto-relacional (ou ORM) é uma técnica de desenvolvimento utilizada para reduzir a redundância da programação orientada a objetos utilizando banco de dados relacionais. As tabelas do banco de dados são representadas através dos modelos do sistema, as classes, e os registros de cada tabela são representados como instâncias das classes correspondentes.

Com esta técnica, o programador não precisa se preocupar com os comandos em linguagem SQL e sua tradução a objetos em sistemas orientados à objetos, ele irá usar uma interface de programação simples que faz todo o trabalho de persistência.

Não é necessária uma correspondência direta entre as tabelas de dados e as classes do programa. A relação entre as tabelas onde originam os dados e o objeto que os disponibiliza é configurada pelo programador, isolando o código do programa das alterações à organização dos dados nas tabelas do banco de dados.

(15)

Existem dois padrões comuns para a comunicação com o BD/Framework: o Data Access Object (DAO) e o Active Record (AR). Os dois, DAO e AR, são padrões bem distintos e refletem abordagens extremamente diferentes na modelagem da aplicação.

2.1.1 - Active Record

Active Record é uma abordagem para acessar dados em um banco de dados. Uma tabela do banco de dados ou view é envolta em uma classe, desta maneira, uma instância é vinculada a uma única linha (registro) na tabela. Após a criação de um objeto, um novo registro é adicionado na tabela. Qualquer objeto carregado obtém informações do seu banco de dados; quando um objeto é atualizado, o registro correspondente na tabela também é atualizado. A classe wrapper implementa os métodos de acesso ou propriedades para cada coluna na tabela ou view.

O Active Record Pattern é comumente usado por ferramentas de persistência de objetos e em mapeamento objeto relacional. Normalmente relacionamentos de chave estrangeira serão expostos como um objeto de tipo apropriado por meio de uma propriedade.

2.1.2 - ActiveRecord do Framework Ruby On Rails

O Active Record se tornou extremamente popular com o framework Rails, para a linguagem Ruby, como a produtividade e simplicidade do framework revoluciona o desenvolvimento, muitos abraçaram o padrão também em outros frameworks. Esse padrão é muito comum em frameworks para linguagens dinâmica, como Python.

(16)

O Active Record fornece acesso conveniente e programático à camada de domínio de nossas aplicações. Ele é um mecanismo de armazenagem persistente que geralmente interage diretamente com o banco de dados relacional, baseia-se e recebe o nome de um padrão de design definido por Martin Fowler em seu livro, Patterns of Enterprise Application Architecture (Addison-Wesley). Neste livro Fowler resume este padrão como:

"Um objeto que encapsula um registro em uma tabela ou view do banco de dados. Além disso, este objeto cuida das rotinas de acesso ao banco e adiciona lógica de domínio às informações encapsuladas."

O Active Record trabalha criando um mapeamento objeto-relacional (ORM) entre os objetos Ruby da aplicação e as linhas e colunas das tabelas no banco de dados. Este mapeamento nos permite interagir com o banco de dados da mesma forma que interagimos com os objetos Ruby, eliminando a necessidade de usar SQL para manipular os dados das tabelas. Em vez de trabalhar com registros nas tabelas, trabalhamos com objetos Ruby, e as colunas das tabelas do banco de dados passam a ser vistas como atributos destes objetos, os quais podemos ler ou escrever usando métodos de acesso.

Um modelo de domínio consiste dos dados e um conjunto de regras que definem como estes dados interagem com o restante da aplicação. O Active Record permite a definição da lógica de nossos modelos de domínio usando Ruby. Com isso há flexibilidade ao definir regras de negócios específicas aos dados, e, uma vez que esta lógica está centralizada no modelo, a alteração se torna muito mais fácil.

O Active Record, assim como boa parte do framework Rails, trabalha com o conceito de "convenção em vez de configuração - convention over configuration" para simplificar os estágios iniciais, assumindo que geralmente os projetos tem padrões em comum. Por exemplo, o Active Record determina os campos da tabela, eliminando a necessidade de

(17)

definir métodos básicos de acesso para cada campo. A forma que o Active Record faz isso é analisando as convenções de nomes de tabelas e campos para mapear o esquema do banco de dados para os objetos Ruby com o mínimo possível de configuração. Os nomes das tabelas são entendidos como sendo o plural do objeto armazenado na tabela. Assim, cada registro de uma tabela "clientes" guarda um "cliente". Além disso, todas as tabelas (exceto tabelas de ligação) devem possuir uma chave primária única chamada id. Chaves estrangeiras (foreign keys) recebem seus nomes baseado no nome da tabela seguido por _id. Por exemplo, uma tabela alunos referenciando uma tabela chamada cursos possuiría uma coluna chamada cursos_id. Tabelas de ligação, usadas em relacionamentos muitos-para-muitos recebem os nomes das duas tabelas envolvidas, com seus nomes em ordem alfabética. Ex: alunos_cursos, artigos_categorias, etc.

Os benefícios da abstração do acesso direto ao banco de dados usando Active Record inclui a habilidade de mudar o banco de dados sempre que necessário, a aplicação não fica dependente de apenas um banco de dados. Uma vez que os detalhes dos dados e suas formas de acesso estão incluídos no Active Record, para mudar de MySQL para PostgreSQL ou SQLite é só editar o arquivo databases.yml no diretório conf do projeto.

Para finalizar, como o Ruby possui a capacidade de instrospecção e metaprogramação de objetos, o Active Record no Rails fornece finders (métodos de pesquisa) dinâmicos baseados em atributos e um bom número de métodos auxiliares que facilitam e tornam a interação com o banco de dados extremamente ágeis.

2.1.3 - Desvantagens do Active Record

(18)

aluno, por exemplo, o Active Record criará um registro na tabela aluno automaticamente. Isso às vezes é ruim, pois não é possível utilizar objetos não persistidos, como na API JPA do Java.

A principal queixa com o Active Record é a sua lentidão para sistemas complexos com uma base de dados muito grande. O programa pode demorar para exibir listas de objetos persistidos e seus atributos, pois além de gerar o SQL necessário de acordo com o banco de dados definido, o resultado é convertido em objetos.

Mas apesar dessa desvantagem, contornada utilizando SQL direto para consultas complexas, o Active Record ainda traz muitos ganhos ao mapear objetos, relacionamentos e automatizar todas as conexões com o banco de dados.

Uma forma de melhorar o desempenho é o uso do cache, que pode manter o resultado das consultas em memória para evitar outras consultas ao banco e páginas préviamente construídas.

2.2 - Sistema de Caching

Cache é uma área de acesso rápido que pode ser utilizada para otimização de sistemas que se utilizam de recursos do sistema. Os dados existentes em cache estão lá duplicados, os dados existem em uma área de armazenamento permanente e no cache. A área de armazenamento permanente, normalmente, é de acesso mais caro, e normalmente o acesso mais caro é compensado pela capacidade superior de armazenamento. Já em áreas de cache o acesso aos dados é mais rápido. Só que a capacidade de armazenamento é menor.

(19)

removido do cache para liberar espaço para o armazenamento de outro recurso.

Apesar de alguns dispositivos de computação terem o nome "cache" contido em seus nomes, cache não é um dispositivo - é um conceito - onde é utilizado recursos de acesso mais rápido para armazenar dados mais, ou recentemente, acessados.

Cache é um bloco de memória temporário para acesso futuro. Para acesso aos dados, um cliente primeiramente consulta sua existência em um cache. Indo ao recurso mais lento apenas se o dado não puder ser encontrado no cache. A este processo se dá o nome de cache hit, utilizado nos navegadores Web recentes. Ao requisitar um endereço na Web, o navegador, primeiramente, verifica se a página solicitada existe no disco local. Se a solicitação (tag) for encontrada no disco local, a página (dado) é exibida sem ir a rede buscá-la.

Em contrapartida, se a solicitação não for encontrada no cache local do browser, o mesmo se encarrega em ir no local destino para buscar a página solicitada. A partir daí a página é inserida no cache para acesso futuro. A esse evento dá-se o nome de cache

miss.

Durante o processo de cache miss o processador de cache se encarrega de prover espaço para entrada do dado mais recentemente acessado que ainda não existia no cache. O algoritmo para o processamento disso chama-se replacement policy.

Existem dois métodos de escrita no cache. Write-through e write-back. No write-through o dado armazenado no cache é gravado sincronamente no local de armazenamento.

No write-back, quando um dado é escrito no cache ele ainda não foi armazenado na área definitiva de armazenamento. O sistema de cache deve se encarregar de escrever o dado na área de armazenamento a fim de precaver-se de perda de dados.

(20)

2.2.1 - Caching on Rails

Em servidores Web é possível implementar funcionalidades se aproveitando do conceito de cache. O objetivo é manter as páginas, já processadas, em uma área temporária para acessos futuros. Com isso é economizado acesso a recursos mais onerosos do sistema armazenando informações recuperáveis por meios mais eficientes. No Ruby on Rails pode-se utilizar de técnicas de cache já implementadas no framework, como cache de páginas ou de SQL a fim de aproveitar recursos do sistema.

2.2.2 - Paging Cache

Por este método, o primeiro cliente que acessar uma determinada página irá processar a página e armazena-la no cache. Com isso o próximo cliente que precisar desta página, não irá esperar o processamento da mesma. Receberá uma cópia já processada.

Esse recurso não pode ser utilizado para páginas em que os dados enviados precisam ser checados para estabelecer uma conexão ao recurso solicitado. É muito utilizado para páginas que são idênticas para todos os usuários que acessam ou para páginas que não precisam de autenticação para serem acessadas.

2.2.3 - Action Cache

Isso resolve o problema existente em paging cache. Antes de servir ao cliente a página em cache, é possível efetuar filtros. Isso utiliza processamento para efetuar as verificações de permissão, por exemplo, e depois serve a página em cache. Assim, uma

(21)

página que depende de autenticação não seria exibida simplesmente por estar em cache.

2.2.4 - Fragment Caching

Como atualmente as páginas Web são mais componentizadas e cada componente da página tem um comportamento diferente, também será necessário aplicação de regras de cache diferente para cada componente da página - para isso o Rails provê este mecanismo.

2.2.5 - Sweepers

Com esta técnica, é possível internalizar o momento de expirar um determinado cache a partir de ações. Quando há um objeto em cache, é necessário que o mesmo seja inválido a partir do momento que algum dado é alterado. Sweeper são pequenos pedaços de código que removem do cache informações que já são antigas, ou devem ser expiradas programáticamente.

2.2.6 - SQL caching

Query cache é uma característica do Rails que permite colocar em cache todo resultset de querys solicitadas pelos clientes. Uma vez solicitada uma consulta que já possui seu resultado em cache o Rails utilizará esse resultado ao invés de consultar novamente no banco de dados. Este recurso está disponível apenas na execução de uma Action.

(22)

2.2.7 - Conditional GET Support

É uma característica da especificação do protocolo HTTP. Ele provê ao Web browser um mecanismo para informar ao Web browser que o recurso solicitado não foi alterado desde sua última solicitação. Então ele pode usar o já existente em seu cache local.

2.3 – View e Templates

O ActionView é a parte do framework responsável pelo tratamento do View, o que é visualizado, na abordagem do Rails para o MVC. O ActionView utiliza os objetos criados pelo controlador e gera a saída, geralmente como HTML ou XML. O ActionView está inserido com o ActionController em uma gem (pacote) Ruby chamada ActionPack. Juntamente com o ActiveRecord, o ActionView e o ActionController formam o núcleo do Rails.

Embora seja possível gerar o conteúdo diretamente a partir do controlador, quase 100% dos aplicativos Rails utilizam o ActionView. O ActionView suporta muitas abordagens diferentes para a gerar a página por meio de um mecanismo de um modelo pré-definido. O ActionView é fornecido com três estilos de modelos. Os modelos Embedded Ruby (Erb) são armazenados em arquivos .rhtml e utilizam um misto de marcação e Erb para a construção do conteúdo dinâmico. Os modelos construtores são armazenados como arquivos .rxml e utilizam o Ruby puro para a construção da saída XML. Os modelos JavaScript são armazenados como arquivos .rjs e utilizam uma API Ruby para a construção da saída JavaScript.

(23)

na arquitetura MVC. O modelo .ehtml ou .rhtml geralmente tem o mesmo nome da ação do controlador. Ou seja, o app/view/bandas/list.ehtml representa o template da ação list do bandas_controller.rb.

2.3.1 - Partials

O partials é um arquivo especial que começa com _, como _itens.ehtml , que é utilizado como um componente reutilizável de modelo de template. Objetos representados igualmente em diferentes partes do sistema são fortes candidato a possuir um único modelo de template parcial.

2.3.2 - Render

As possíveis chamadas à visão pelo controlador.

Action:

render :action => 'some_action'

render :action => 'some_action', :layout => 'another_layout'

Partial:

render :partial => 'subform'

render :partial => 'error', :status => 500

render :partial => 'subform', :locals => { :variable => @other_variable } render :partial => 'listitem', :collection => @list

Template:

(24)

Arquivo:

render :file => '/path/to/some/file.rhtml'

render :file => '/path/to/some/filenotfound.rhtml', status => 404, :layout => true

Texto:

render :text => "Hello World"

render :text => "This is an error", :status => 500 render :text => "Let's use a layout", :layout => true render :text => 'Specific layout', :layout => 'special'

Template Inline:

render :inline => "<%= 'olá novamente' %>"

Redefinindo o content-type:

render :action => "status", :content_type => "application/json” render :json => “texto”.to_json

Além da eficiente integração dos controladores com a view, a elaboração dos .rhtml não diferem muito das aplicações como ASP e PHP, sendo utilizado Ruby puro. Porém há o foco na arquitetura RESTful, onde cada recurso tem uma representatividade bem definida, um Identificador Uniforme de Recurso, facilitando a manipulação das entidades do

sistema de informação, como melhor apresentado no roteamento das URLs.

2.3.4 - RHTML

Modelo de template que gera links para todos os últimos álbuns.

<% @ultimos_albuns.each do |album| %> <li>

(25)

<%= link_to album_name(album), album_path(album) %> </li>

<% end %>

Modelo de template que gera links para todas as bandas e seu número de álbuns.

<% @bandas.each do |banda| %> <li>

<%= link_to "#{banda.nome} (#{banda.albuns.count})", banda_path(banda) %> </li>

<% end %>

2.3.5 - Helpers

Helpers são classes auxiliadoras para fornecer métodos para as views.

Supondo a necessidade de um método de formatação para que apenas os dez primeiros caracteres de uma determinada string sejam exibidos, o método so10() poderia ser definido no helper.

# “esse texto é muito grande” => “esse texto ...” def so10(str)

str[0..10]+"..." end

E utilizado num template:

<h2>so10(@artigo.comentario)</h2>

(26)

imagem do Google Imagens, dado um termo, como o nome de um álbum de banda, usando a API do Google.

def getAlbumImage(album) google_image = nil banda_nome = CGI.escape('"'+album.banda.nome+'"') album_nome = CGI.escape('"'+album.nome+'"') query = "#{banda_nome}+#{album_nome}" url = "http://ajax.googleapis.com/ajax/services/search/images?hl=pt-BR&rsz=large&start=#{position=0}&v=1.0&q=#{query}" results = JSON.parse(open(url).read) image_array = results['responseData']['results'] if image_array && image_array[0]

image = image_array[0]

google_image = {:thumbnail => image['tbUrl'], :original => image['unescapedUrl'], :name => query.titleize} end

Assim, representamos álbuns não só pelo seu nome, mas exibindo suas capas como se fossem de nosso próprio domínio.

2.4 - Roteamento de URLs

Roteamento Rails é um dos conceitos mais inovadoras e importantes do Framework, que conecta as solicitações HTTP com os controllers da aplicação e ajuda a gerar URLs automáticas sem ter que ser codificadas como strings.

2.4.1 - Conectando URLs com o código

(27)

local apropriado na sua aplicação.

Quando a aplicação Rails recebe uma solicitação HTTP de entrada, como

GET /livros/17

Neste caso, a aplicação provavelmente executaria a action show dentro do controller livros, mostrando os detalhes do livro cujo ID é 17.

2.4.2 - Gerando URLs do código

O roteamento também funciona no caminho reverso. Em uma aplicação que contém o código:

@livro = Livro.find(17)

<%= link_to "Livro Grande", livro_path(@livro) %>

Então a engine de roteamento é a parte que traduz o link para a URL, assim como http://example.com/livros/17. Usando o roteamento desta maneira, pode-se reduzir a fragilidade da aplicação se comparada com uma aplicação com URLs codificada, além de tornar o código fácil de ler e entender.

Livro necessita ser declarado como um recurso mapeado para que este estilo de tradução por rotas nomeadas esteja disponível.

2.4.3 - Routes.rb

(28)

fornecida como parte do Rails, e o arquivo config/routes.rb, que contém as rotas atuais que serão usadas pela aplicação. É nesse importante arquivo que todas as requisições ao sistema devem ser repassadas aos devidos controladores para serem devidamente respondidas. Rotas podem ser definidas a partir de expressões regulares. O arquivo routes.rb define todas as requisições que o sistema é capaz de responder.

2.4.4 - Processando o arquivo

O routes.rb não é nada mais que um grande bloco enviado para ActionController::Routing::Routes.draw. Dentro do bloco, pode-se ter comentários, mas é provável que a maior parte do conteúdo seja de linhas individuais de código – cada linha sendo uma rota na aplicação. Existem cinco tipos principais de conteúdo que estarão neste arquivo:

• Rotas RESTful (RESTful Routes)

• Rotas Nomeadas (Named Routes)

• Rotas Aninhadas (Nested Routes)

• Rotas Regulares (Regular Routes)

• Rotas Padrão (Default Routes)

O arquivo é processado de cima para baixo quando chega uma requisição. A requisição será despachada para a primeira rota que combine. Se nenhuma rota combina, então o Rails retorna o status HTTP 404 ao chamador.

(29)

2.4.5 - Rotas RESTful

Rotas RESTful tiram vantagem da orientação do REST embutido no Rails para empacotar muitas das informações de roteamento em uma simples declaração. Uma rota RESTful se parece como esta:

map.resources :livros

2.4.6 - Rotas Nomeadas

Rotas nomeadas nos dão links muito legíveis no seu código, bem como manipulação de solicitações recebidas. Exemplo típico de rota nomeada:

map.login '/login', :controller => 'sessions', :action => 'new'

2.4.7 - Rotas Aninhadas

Rotas aninhadas permitem-nos declarar que um recurso está contido dentro de outro recurso.

2.4.8 - Rotas Regulares

Em muitas aplicações, há roteamento não RESTful, que conecta explicitamente cada parte da URL a uma ação em particular. Por exemplo,

(30)

2.4.9 - Rotas Padrão

As rotas padrão são uma rede de proteção para tratar requisições sem uma rota pré-definida. Muitas aplicações Rails contém este par de rotas como padrão:

map.connect ':controller/:action/:id'

map.connect ':controller/:action/:id.:format'

Estas rotas padrão são geradas automaticamente em toda nova aplicação Rails.

2.4.10 - Roteamento RESTful: o Padrão Rails

Roteamento RESTful é o padrão atual de roteamento no Rails.

REST é um acrônimo para Representational State Transfer, que resume-se em dois princípios fundamentais:

• Usando identificadores de recurso (na qual, para o propósito da discussão, você pode pensar como as URLs) para representar recursos

• Transferindo representações de estados entre recursos e componentes do sistema. Por exemplo, para uma aplicação Rails, uma requisição como esta:

DELETE /livros/17

seria entendida como uma referencia a um recurso livro com o ID 17, e indicaria a ação desejada – deletar este recurso. REST é um estilo natural para a arquitetura de aplicações Web e Rails faz isso de uma forma mais natural, usando convenções para proteger você de algumas complexidades do RESTful.

(31)

3 - Estudo de caso

Para demonstrar o aumento na produtividade de tais conceitos incorporados no framework para o desenvolvimento dos ditos Sistemas da Web 2.0 desenvolvemos e publicamos dois sistemas com uma curva de aprendizado mínima.

baixogavea.com – Um sistema colaborativo, repositório de bandas e URLs de acesso aos downloads de álbuns que busca a capa automáticamente no Google Imagens. Chegou ao pico de receber 328 nomes de bandas em um só dia e já conta hoje com 65 usuários e mais de 1500 álbuns. Foi desenvolvido em cerca de 35 horas.

mostre.me – Um redirecionador HTTP que segue o conceito de URL elegante e infere onde um determinado link foi referenciado e quantos clicks recebeu. Possui aproximadamente 150 URLs cadastradas e foi desenvolvido em cerca de 12 horas.

3.1 - Estudo de caso - baixogavea.com

Escolhemos o site baixogavea.com como caso de uso a apresentar pois ele utiliza de forma mais completa boa parte dos conceitos revisados.

3.1.1 – Criação do Projeto

Executando o comando “rails BaixoGavea” é gerada uma pasta com todos os arquivos necessários para o projeto, disponibilizados entre os diretórios:

(32)

3.1.2– Definição do SGBD

No arquivo config/databases.yml é definida todas as configurações do banco de dados, de forma que migrar de um SQLite para um Oracle tenha o mínimo de trabalho.

development: adapter: sqlite3 database: db/dev_baixogavea.db pool: 5 timeout: 5000 test: adapter: sqlite3 database: db/test_baixogavea.db pool: 5 timeout: 5000 production: adapter: mysql encoding: utf8 reconnect: false database: prod_baixogavea pool: 8 username: polo password: ******** host: db.baixogavea.com 3.1.3 – Definição do Schema

O arquivo db/schema.rb é inspirado na definição e criação de tabelas em SQL, mas em Ruby, funcionando como uma linguagem universal para a criação e migração entre vários

(33)

SGBDs.

ActiveRecord::Schema.define(:version => 20091028) do create_table "albuns", :force => true do |t|

t.string "nome", :limit => 50, :null => false t.string "atalho", :limit => 50, :null => false t.date "ano", :null => false

t.integer "banda_id", :limit => 6, :null => false t.integer "user_id", :limit => 6, :null => false t.datetime "created_at"

t.datetime "updated_at" end

add_index :albuns, :atalho

create_table "bandas", :force => true do |t| t.string "nome", :limit => 35, :null => false t.string "atalho", :limit => 35, :null => false t.integer "user_id", :limit => 6, :null => false t.datetime "created_at"

t.datetime "updated_at" end

add_index :bandas, :atalho

create_table "links", :force => true do |t| t.string "dominio", :limit => 60, :null => false t.string "url", :null => false

t.string "comentario"

t.integer "album_id", :limit => 6, :null => false t.integer "user_id", :limit => 6, :null => false t.datetime "created_at"

(34)

t.datetime "updated_at" end

create_table "votos", :force => true do |t| t.integer "link_id", :limit => 6, :null => false t.integer "user_id", :limit => 6, :null => false t.integer "ponto", :limit => 1, :null => false t.string "comentario", :null => false

t.datetime "created_at" end

create_table "users", :force => true do |t| t.string "username", :limit => 15, :null => false t.string "normalizado", :limit => 15, :null => false t.string "email", :null => false

t.string "senha", :limit => 15, :null => false t.string "info"

t.integer"confirmado", :default=>0, :null => false t.datetime "created_at"

t.datetime "updated_at" end

add_index :users, :username end

3.1.4 – Modelos

Os modelos são classes em Ruby que garantem toda a integridade do domínio do sistema e herdam diretamente as funcionalidades do ActiveRecord, logo suas instâncias representam todos os objetos persistidos como tuplas no SGBD.

(35)

Todos os comportamentos do ciclo de vida dos objetos podem ser definidos diretamente nessas classes através de métodos padrões como before_create, after_create,

before_save, after_save.

Os atributos has_one, belongs_to, has_many e has_and_belongs_to_many

definem as associações entre as entidades que logo podem ser manipuladas e testadas pelo console.

(36)

Exibiremos apenas três modelos para fins demonstrativos.

Banda.rb

class Banda < ActiveRecord::Base belongs_to :user

has_many :albuns, :dependent => :destroy

validates_uniqueness_of :nome, :message=>"já foi inserido" validates_presence_of :nome, :user

validates_length_of :nome, :in=>3..35, :message=>"deve ter entre 3 e 45 caracteres"

before_create

# Chico Buarque => chico_buarque

self.atalho = self.nome.strip!.downcase.gsub(“ ”, “_”) end

User.rb

class User < ActiveRecord::Base has_many :links

has_many :albuns has_many :bandas

validates_uniqueness_of :username, :email, :message=>"já foi inserido" validates_uniqueness_of :normalizado, :message=>". Escolha outro username" validates_presence_of :username, :info, :email, :senha

validates_format_of :email, :with=>/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/ validates_length_of :senha, :in=>6..15, :message=>"deve ter entre 6 e 15 caracteres"

(37)

validates_length_of :username, :in=>4..15, :message=>"deve ter entre 4 e 15 caracteres" end

Link.rb

class Link < ActiveRecord::Base belongs_to :album

belongs_to :user has_many :votos

validates_uniqueness_of :url, :message=>"já foi cadastrada" validates_presence_of :url, :album, :user

validates_format_of :url, :message=>"deve ter o formato de uma URL", :with => /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix

def after_create

Tuitero.diz("#{self.user.username} adicionou um link para #{self.album.banda.nome}) end

Tuitero é uma classe desenvolvida apenas com o método estático diz(string) que informa no twitter @baixo_gavea toda a criação de um novo objeto link. Se encontra em

lib/tuitero.rb.

3.1.5 – Migrando e Testando

Uma das coisas mais interessantes do ambiente de desenvolvimento do Rails são suas inspirações nos sistemas UNIX. Existem vários comandos na pasta scripts como o rake “ruby make”, inspirado no comando make, além de performance dbconsole, e console que permite manipular os modelos (bandas, albuns, usuarios, links, votos, ) por um terminal.

(38)

definido na configuração, no caso do nosso ambiente de produção, o MySQL.

Pelo console já é possível manipular e testar todos os modelos do sistema.

Criando um usuário:

user = User.create(:username=>"usuario", :email=>"user@bennett.br", :senha=>"1234567", :confirmado=>1, :info=>"perfil de teste")

e uma banda como sua autoria:

chico = Banda.create(:nome=>"Chico Buarque", :user_id=>user)

e a excluíndo

chico.destroy

ou excluíndo todas as suas bandas

Banda.find_all_by_user_id(user.id).each do |b| b.destroy

end

A metaprogramação e introspecção natural da linguagem Ruby permite que a classe seja capaz de reconhecer e criar métodos de acordo com seus atributos do schema, como:

Banda.find_by_nome ou User.find_by_nome_and_email

(39)

3.1.6 – Roteando as requisições HTTP aos controladores

Diferente da maioria dos projetos Web feitos em ASP, JSP ou PHP cujas URLs remetem diretamente ao arquivo servido, como http://www.site.com/diretorio/arquivo.php, todas as requisições no Rails são roteadas à controladores e ações específicas, que podem ser, inclusive, direcionadas a partir de expressões regulares.

Ao projetar o sistema definimos que cada banda, álbum e usuário teriam sua própria representatividade inequívoca, como defende o REST:

http://baixogavea.com/chico-buarque

http://baixogavea.com/chico-buarque/roda-vida http://baixogavea.com/usuario/polo

Dessa forma o routes.rb deve ter,

map.connect ':banda', :controller => "bandas", :action=>"show" map.connect ':banda/:album', :controller => "albuns", :action=>"show" map.connect 'usuario/:user', :controller => "users", :action=>"show"

Realizando as chamadas análogas, Bandas.show(:banda)

Albuns.show(:banda, :album) Users.show(:user)

Onde cada modelo de classe possui seu próprio controlador, dependendo da arquitetura, respeitando o MVC.

O arquivo conf/routes.rb do sistema e suas principais ações como autenticação e pesquisa é descrito abaixo.

(40)

ActionController::Routing::Routes.draw do |map| map.root :controller => "bandas", :action=>"index"

map.connect "login", :controller => "users", :action=>"login" map.connect "logout", :controller => "users", :action=>"logout" map.connect "novo_usuario", :controller => "users", :action=>"novo"

map.connect "pesquisa/termo", :controller => "pesquisa", :action=>"pesquisa"

map.connect 'bandas/:letra', :controller => "bandas", :action=>"index", :requirements => { :letra => /\w/ } map.connect 'nova_banda', :controller => "bandas", :action=>"new"

map.connect 'usuario/:user', :controller => "users", :action=>"show"

map.connect 'user/update/:id', :controller => "users", :action=>"update_status" map.connect ':banda', :controller => "bandas", :action=>"show"

map.connect ':banda/novo_album', :controller => "albuns", :action=>"new" map.connect ':banda/:album', :controller => "albuns", :action=>"show" map.connect ':banda/:album/novo_link', :controller => "links", :action=>"new" end

Em geral, um controlador possui ações referentes aos métodos CRUD (Create, Update, Delete) de um dado recurso, mas não é limitado à eles e com frequência toda ação gera uma saída no view através dos templates.

O Controlador de álbuns, albuns_controller.rb, demonstrado a seguir, possui as ações index, show, new, edit, new_album_link, create, update, excluir e destroy. Praticamente todas essas ações possuem um template associado, como app/view/albuns/edit.rhtml.

As variáveis com @ (arroba) são as váriaves de classe em Ruby utilizadas para acessar os dados dos modelos no template – do Modelo à Visão, mediada pelo Controle.

AlbunsController < ApplicationController def index

(41)

@albuns = Album.all respond_to do |format| format.html # index.html.erb end end def show banda = Banda.find_by_atalho(params[:banda])

@album = Album.find_by_atalho_and_banda_id(params[:album], banda) @page_title = banda.nome + " | " + @album.nome

if !@album

flash[:notice] = "Não existe esse álbum aqui. Adicione!" redirect_to("/")

return end

respond_to do |format| format.html # show.html.erb

format.xml { render :xml => @album } end end def new @album = Album.new @banda = Banda.find_by_atalho(params[:banda]) respond_to do |format| format.html # new.html.erb end end def edit

(42)

@album = Album.find(params[:id]) if @album.user.id != session[:user]

flash[:notice] = "Você só pode editar as bandas que adicionou." redirect_to("/") return end end def new_album_link(album) "/#{album.banda.atalho}/#{album.atalho}/novo_link" end def create @album = Album.new(params[:album]) @banda = @album.banda @album.user_id = session[:user] respond_to do |format| if @album.save

flash[:notice] = "O novo álbum foi adicionado."

format.html { redirect_to(new_album_link(@album), :banda=>@album.banda.atalho, :album=>@album.atalho) }

format.xml { render :xml => @album, :status => :created, :location => @album.atalho } else

format.html { render :action => "new" } end

end end

def update

(43)

if @album.user.id != session[:user]

flash[:notice] = "Você só pode editar as bandas que adicionou." redirect_to("/")

return end

respond_to do |format|

if @album.update_attributes(params[:album]) flash[:notice] = 'O Álbum foi editado com sucesso.' puts "/#{@album.banda.atalho}/#{@album.atalho}/"

format.html { redirect_to("/#{@album.banda.atalho}/#{@album.atalho}/") } format.xml { head :ok }

else

format.html { render :action => "edit" }

format.xml { render :xml => @album.errors, :status => :unprocessable_entity } end end end # pré def excluir @album = Album.find(params[:id]) #album.destroy

flash[:notice] = "Hey! Mesmo, mesmo, #{session[:username]}?" end

def destroy

@album = Album.find(params[:id]) user = @album.user

(44)

if session[:user] == user.id @album.destroy

flash[:notice] = 'Álbum excluído!' else

flash[:notice] = 'Você só pode excluir o que adicionou!' end puts user_path(user) respond_to do |format| format.html {redirect_to("/usuario/#{user.username}")} end end end

A ação login do controlador de users.

def login

if params[:user]

log_user = params[:user]

@user = User.find_by_username_and_confirmado(log_user[:username], "1") if !@user

flash[:notice] = "Usuário não existe." else

if @user.senha == log_user[:senha] session[:user] = @user.id

session[:username] = @user.username session[:logged] = true

flash[:notice] = "Bem-Vindo #{@user.username}!" redirect_to session[:href] ? session[:href] : "/" return true

(45)

flash[:notice] = "Senha incorreta!" end

end end

3.1.7 - Visualizando as respostas através dos templates

Como notado nas ações do controlador acima, as ações chamam respond_to ou redirect_to para invocar uma view.

O application_controller é responsável por definir qual será o layout padrão do sistema, apesar de cada controlador poder incluir seu próprio layout.

class ApplicationController < ActionController::Base layout "geral"

end

O layout geral localizado em app/view/layout/geral.html.erb atua como um container. É só nele que ficam, por exemplo, o head do HTML chamando os scripts e estilos necessários. No body do documento incluímos o yield onde todas as saídas geradas pelos controladores são exibidas.

<html> <head>…</head> <body> <div id="meiuca"> <%= yield %> </div> </body> </html>

(46)

Ou seja, a requisição baixogavea.com/chico-buarque é roteada para a ação show do controlador album – definido em routes.rb - que gera a saída do arquivo app/views/album/show.html.erb no yield do template geral passando o objeto @banda = Banda.find_by_atalho(params[:banda]), onde :params[:banda] é “chico-buarque”.

3.1.8 - AJAX

O Rails, em sua versão 2.3.4, possui inúmeras técnicas de geração de saída com templates no view, incluíndo o parsing de objetos em arquivos .xml em apenas uma linha:

respond_to do |format| format.xml { render :xml => @banda } end

Poder ter todas as requisições respondidas em XML, JSON ou Atom torna o sistema independente de uma única interface de usuário e até independente do Browser, implementando a view da aplicação por requisições AJAX em diferentes dispositivos como iPhones ou Palms, como demostra a figura abaixo que representa o funcionamento da técnica.

(47)

O Rails vem com um helper baseado num popular framework para javascript chamado Prototype, que consiste em auxiliadores para efeitos visuais, requisições Ajax e manipulações do DOM (Documento Object Model) do browser do cliente.

No rodapé da página realizamos uma requisição AJAX para exibir em tempo real o status do sistema, solicitando o arquivo stats.json que é roteado e gerado a cada requisição da ação stats em stats_controller.

app/controllers/stats_controller.rb

class StatsController < ApplicationController def stats bandas_count = Banda.count albuns_count = Album.count users_count = User.count stats = { "users_count"=> users_count, "bandas_count"=> bandas_count, "albuns_count"=>albuns_count } headers["Content-Type"] = "application/json" render :json => stats.to_json

end end app/views/layouts/_rodape.html.rhtml new Ajax.Request('/stats.json', { method:'get', onSuccess: function(response){

(48)

var json = response.responseText.evalJSON();

var stats = json.users_count + " usuários > " + json.bandas_count+ " bandas > " + json.albuns_count + " álbuns";

$("stats").innerHTML = stats; }

});

adição em config/routes.rb

map.connect "stats.json", :controller => "stats", :action=>"stats"

4- Resultados e Conclusões

Apesar de existirem plugins para as duas principais IDEs open-source, o NetBeans e o Eclipse, sistemas complexos, como compiladores ou interpretadores de linguagem natural, podem ter desvantagens diante de uma linguagem dinâmica como Ruby, uma vez que a meta-informação de uma linguagem de tipo estático é capaz de prevenir erros antes de serem compiladas ou interpretadas. Em uma linguagem de tipo dinâmico, o tipo de uma variável ou método é desconhecido até a execução do programa.

Ou seja, as linguagens dinâmicas exigem um cuidado maior com a manipulação e integridade dos dados na mesma medida que dão liberdade de expressão.

Questões importantes como testes foram deixadas de lado em nossa abordagem ágil, mas o Rails já tem suporte para uma vasta gama de técnicas e plugins para garantir e acompanhar a qualidade do código, tal como o JUnit no Java, desenvolvido por uma grande comunidade de desenvolvedores.

(49)

desenvolvedores é a possibilidade de gerenciamento de bibliotecas de terceiros, chamados gems, através de um repositório global em rubyforge.org, inspirado no APT (Advanced Package Tool) dos sistemas UNIX.

Para instalar a biblioteca do conector de sqlite3 pro Ruby:

gem install sqlite3-ruby

Instalar a biblioteca que gera o desenho dos modelos:

gem install railroad

Outras gems comumente usadas são as de tradução do Rails para português, a que permite acesso aos álbuns do Flickr e as gems que funcionam como wrapper das APIs do Google.

De um rascunho em UML da arquitetura desejada do sistema à codificação de seus modelos e seus controladores, erguemos um protótipo totalmente funcional em poucas horas – todos os recursos do sistema eram manipulados através de requisições HTTP às URLs dos objetos. Aos poucos refinamos seus templates, o view, e tratamos possíveis exceções nos controladores, preparamos o servidor com um módulo especial no Apache, tal como com a configuração de um ambiente PHP, mudamos o config/environment.rb para ambiente de produção, ENV['RAILS_ENV'] = 'production', subimos a pasta do projeto com menos de dois megabyte por FTP e com o comando “rake db:schema:load” por SSH todo o SGBD MySQL estava preparado e o sistema de pé na World Wide Web.

No princípio questionávamos se esse novo paradigma além de prover um desenvolvimento ágil, também resultaria em sistemas eficientes e escaláveis para a Web. Para nossa surpresa, a maior referência de sistema colaborativo na Web 2.0 contemporânea, o Twitter, foi desenvolvido com o Ruby on Rails, sendo a prova de um

(50)

site relativamente estável e escalonável com milhões de pageviews diárias. No dia 25 de Setembro o baixogavea.com foi comentário entre dois grandes coletivos de compartilhamento de música na Web brasileira, o Som Barato e a Revista Pernambucana O Dilúvio, tendo resultado em aproximadamente 10 mil pageviews e cerca de 350 novos álbuns inseridos em poucas horas sem sequer a necessidade do cache habilitado no projeto em nosso servidor compartilhado.

No acumulo de experiências com frameworks Web fica claro que o desenvolvimento de modelos de comércio eletrônico como o eBay e o Submarino, redes sociais como o Facebook e o Twitter, front-ends de consultas e toda uma geração de novas Internet

Applications utilizando Rails têm muitas vantagens, agilizando os complexos padrões de

configurações, como as notações transversais do Hibernate e do Struts - ainda bem aceitos pelo mercado – integrando, através de uma única linguagem, o Ruby, a implementação, o acesso ao banco de dados e a própria configuração do projeto.

4.1 – Trabalhos Futuros

• Integrar links especificados pelo protocolo BitTorrent, armazenando a quantidade de semeadores e consumidores (seeds e leechs) de cada tracker, servidor, para cada link.

(51)
(52)

REFERÊNCIAS BIBLIOGRÁFICAS

JUSTIN GEHTLAND, STUART DABBS HALLOWAY. Rails para Programadores Java. USA: The Pragmatic Bookshelf, 2007

SHORE J., WARDEN S. The Art of Agile Development. USA: O’Reilly, 2008.

Representational State Transfer. Disponível em:

http://en.wikipedia.org/wiki/Representational_State_Transfer [capturado em novembro de 2009].

Rails Guides. Disponível em:

http://guias.rubyonrails.pro.br [capturado em novembro de 2009].

Ruby on Rails : Documentation. Disponível em:

http://rubyonrails.org/documentation [capturado em setembro de 2009].

Building Web Services the REST Way. Disponível em:

http://www.xfront.com/REST-Web-Services.html [capturado em setembro de 2009].

Naming and Addressing: URIs, URLs, ... Disponível em: http://www.w3.org/Addressing/ [capturado em setembro de 2009].

Architectural Styles and the Design of Network-based Software Architectures. Disponível em:

http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm [capturado em setembro de 2009].

Referências

Documentos relacionados

Apesar de pesquisadores na França, na Inglaterra e no Brasil (e talvez em outros tantos lugares) terem identificado igualmente seus processos de fixação da imagem

b) Execução dos serviços em período a ser combinado com equipe técnica. c) Orientação para alocação do equipamento no local de instalação. d) Serviço de ligação das

Os interessados em adquirir quaisquer dos animais inscritos nos páreos de claiming deverão comparecer à sala da Diretoria Geral de Turfe, localizada no 4º andar da Arquibancada

segunda guerra, que ficou marcada pela exigência de um posicionamento político e social diante de dois contextos: a permanência de regimes totalitários, no mundo, e o

Portanto, mesmo percebendo a presença da música em diferentes situações no ambiente de educação infantil, percebe-se que as atividades relacionadas ao fazer musical ainda são

The user uses GIS to generate a map with a visual representation of the location and extent of the active containment zones in September 2013 and information about the measures

Os resultados são apresentados de acordo com as categorias que compõem cada um dos questionários utilizados para o estudo. Constatou-se que dos oito estudantes, seis

A iniciativa parti- cular veiu em auxílio do govêrno e surgiram, no Estado, vá- rios estabelecimentos, alguns por ventura falseados em seus fins pelos defeitos de organização,