FATEC – SP
Faculdade de Tecnologia de São Paulo
Desenvolvimento ágil
com Ruby on Rails
São Paulo, SP
2010
FATEC – SP
Faculdade de Tecnologia de São Paulo
Desenvolvimento ágil
com Ruby on Rails
Ricardo Augusto da Costa
Monografia apresentada à Faculdade de
Tecnologia de São Paulo para a obtenção do
Grau de Tecnólogo em Processamento de Dados
Prof. Orientador: Sérgio Luiz Banin
São Paulo, SP
2010
Agradecimentos:
Ao Orientador Prof. Sérgio Luiz Banin pelo
incentivo e presteza no auxílio às atividades e discussões
sobre o andamento e normatização desta Monografia de
Conclusão de Curso.
A Essy Naira Ayako Tsuda e a Marcia Cardenas
pela orientação e suporte durante todo o processo de
realização desta monografia.
Ao colega de trabalho Tiago Pleffer pelo auxilio
na pesquisa e no desenvolvimento.
A empresa ADV Tecnologia e ao meu chefe
Paulo Henrique Azevedo pelo apoio e incentivo,
fornecendo livros e ajudando a participar de conferências
e palestras sobre o tema abordado.
Índice
INTRODUÇÃO..............................................................................................................01
1 CONCEITOS BÁSICOS........................................................................................... 03
1.1 O que é Ruby ?.......................................................................................... 03
1.2 Características da linguagem Ruby........................................................... 04
1.3 O que são Ruby Gems ?............................................................................ 05
1.4 O que é MVC ?.......................................................................................... 06
1.5 O que é Rails?............................................................................................ 08
2 A LINGUAGEM RUBY........................................................................................... 09
2.1 Instalando o ruby....................................................................................... 09
2.2 Programando em ruby............................................................................... 10
2.2.1 As convenções do Ruby................................................................. 11
2.2.2 Os Arrays....................................................................................... 12
2.2.3 Retorno de métodos....................................................................... 13
2.2.4 Criando classes no ruby................................................................. 13
2.2.5 Herança em Ruby........................................................................... 15
2.2.6 Polimorfismo e interfaces.............................................................. 16
2.2.7 Os Hashes...................................................................................... 17
2.2.8 Como funciona o CompareTo........................................................ 18
2.2.9 Metaprogramação.......................................................................... 18
2.2.10 Closures......................................................................................... 20
3 RAILS........................................................................................................................ 22
3.1 Começando a usar o rails........................................................................... 23
3.2 A primeira aplicação no rails..................................................................... 27
3.2.1 O plugin ActiveScaffold.................................................................. 30
4 CRIAÇÃO DE CADASTROS COM RAILS E ACTIVE SCAFFOLD (CRUD).... 45
4.1 Demonstração do desenvolvimento Ruby X Delphi................................. 45
4.2 Análise comparativa de criação de telas de cadastro Delphi X
RubyOnRails................................................................................................................... 73
5 IMPLEMENTAÇÃO DE VALIDAÇÕES.............................................................. ..75
5.1 Análise comparativa com Delphi............................................................ ..77
6 SEGURANÇA EM RAILS..................................................................................... ..79
6.1 As principais formas de invasão na Web................................................ ..79
6.2 As proteções nativas do rails................................................................... ..80
6.3 Análise comparativa com PHP................................................................ ..81
CONCLUSÃO.............................................................................................................. ..83
BIBLIOGRAFIA.......................................................................................................... ..84
Lista de Figuras
Figura 1 - Tela inicial do cadastro de Contatos........................................................... 42
Figura 2 - A consulta é feita em qualquer campo do cadastro..................................... 42
Figura 3 - Tela de inclusão........................................................................................... 43
Figura 4 - Tela de edição.............................................................................................. 43
Figura 5 - Excluindo um registro.................................................................................. 44
Figura 6 - Tela inicial do cadastro de clientes.............................................................. 56
Figura 7 - Tela de inclusão de cadastro........................................................................ 57
Figura 8 - Consulta de Clientes.................................................................................... 57
Figura 9 - Cadastro de Clientes em Delphi...................................................................67
Figura 10 - Cadastro de Vendedores............................................................................ 69
Figura 11 - Cadastro de Produtos................................................................................. 72
Figura 12 - Exemplo de mensagem de validação de campo........................................76
Lista de Abreviaturas
1. CRUD – Create Retrive Update Delete. Significa uma tela de cadastro com as
funções de Inserir, Consultar, Alterar e Excluir.
2. MVC – Model View Controller. É um padrão de arquitetura de software.que visa
separar a regra de negócios da lógica de apresentação através de três camadas
(modelo, visão e controlador).
3. REST - Representational State Transfer ou Transferência de Estado
Representacional. É uma técnica de engenharia de software para sistemas
hipermídia distribuídos como a World Wide Web
4. SOAP. Simple Object Access Protocol, ou Protocolo Simples de Acesso a Objetos,
é um protocolo para troca de informações estruturadas em uma plataforma
descentralizada e distribuída.
5. WSDL - Web Services Description Language (WSDL) é uma linguagem baseada
em XML utilizada para descrever Web Services
CURRICULUM VITAE
Ricardo Augusto da Costa, nascido em 02/03/1989 em São Paulo–SP. Formado em Técnico de Informática na ETESP, está cursando Processamento de Dados pela Fatec-SP. Atualmente é programador na empresa ADV Tecnologia e trabalha com o desenvolvimento de sistemas ERP em ambiente web e desktop.
Resumo
Este é um trabalho que busca estudar a produtividade do desenvolvimento web
através do Ruby on Rails. O foco será no desenvolvimento de sistemas baseado em
CRUD.
Para tal, serão elucidados os conceitos básicos do Ruby on Rails e demonstrado
as principais formas de obter produtividade no desenvolvimento web de aplicações com
o Ruby.
Como essa linguagem ainda não é tão popular quanto outras linguagens de
mercado (com Java, PHP, C#,etc), serão demonstrado o processo de instalação e
configuração do ambiente.
E em seguida será demonstrado um pouco da sintaxe e algumas características
da linguagem, para familiarização e entendimento dos estudos que serão feitos
posteriormente.
Para analisar a eficiência da ferramenta será feita uma comparação entre Ruby,
Delphi e PHP. Com o Delphi será estudado a criação de telas CRUD, e com o PHP será
abordada a segurança web.
Abstract
This is a coursework that seeks study the productivity about web development
through Ruby on Rails. The focus will be on development of CRUD based systems.
For this, will be explained the basics concepts of Ruby on Rails and showed the
main forms to get productivity in web applications development with Ruby
Because this language is not as popular as other famous languages (eg: Java,
PHP, C#, etc), will be showed the steps to install and to configure the environment.
After, will be demonstrated a little of syntax and some language features, to
make the language friendly and enable the understanding for the future study.
To analyze the tool efficiency, will be made the comparing among Ruby, Delphi
and PHP. With Delphi will be study the CRUD development and with PHP will be
explained about the web safely.
1
INTRODUÇÃO
Com a popularização da internet e com a evolução da Cloud Computing, o
desenvolvimento de sistemas web está virando uma tendência do mercado, devido a
características importantes como: ser multiplataforma, ter facilidade na manutenção por
ser centralizado, ser acessível de qualquer lugar que disponibilize de conexão com
internet e um browser com os plugins necessários (Java, flash, suporte a JavaScript,
etc), permitir uma infra-estrutura com um custo reduzido em relação à sistemas que
rodam em ambiente desktop, facilidade no controle contra a pirataria, etc. Essas
vantagens costumam atrair desenvolvedores para o ambiente web, mesmo em frente aos
problemas como: segurança (que são muito comuns na web e complexos de resolver),
falhas na conectividade que deixam o sistema inteiro fora do ar (falta de internet,
principalmente no Brasil que ainda não tem uma conexão de boa qualidade), etc.
Porém o desenvolvimento web, comparado ao desenvolvimento desktop, ainda
costuma ser improdutivo, lento e trabalhoso (principalmente quando comparado com
ferramentas ágeis como o Delphi). Muitos desenvolvedores web encontram dificuldade
em tarefas simples e muitos desenvolvedores desktop deixam de migram para o
ambiente web por considerá-lo improdutivo.
Esta pesquisa sugere um alternativa de ambiente de desenvolvimento web mais
eficiente que as ferramentas atuais e tão eficaz quanto, obtendo a mesma produtividade
do desenvolvimento desktop sem perder as vantagens de um ambiente web.
2
Para isso será demonstrado o processo de desenvolvimento com o Ruby, desde a
instalação e configuração de seus principais frameworks até o desenvolvimento de telas
que justificam sua eficiência. Serão mencionados alguns conceitos da sintaxe da
linguagem que não serão muito aprofundados, apenas mostrado o essencial para que se
possa ter entendimento das demonstrações no desenvolvimento, onde se terá maior
ênfase.
3
1 CONCEITOS BÁSICOS
1.1 O que é Ruby ?
Ruby é uma Linguagem de programação interpretada, com Tipagem Dinâmica
(ou seja, diferente de Java e C++, o tipo do objeto só é conhecido em runtime) e
Tipagem Forte, orientada a objetos, com várias semelhanças com Perl, Python e
SmallTalk.
Projetada tanto para a programação em grande escala quanto para codificação
rápida, tem um suporte a orientação a objetos que tem o objetivo de ser simples e
prático. A linguagem, escrita em C, foi criada pelo japonês Yukihiro Matsumoto (Matz)
, que aproveitou o que considerou serem as melhores idéias das outras linguagens da
época (Perl and Python).
Matz decidiu desenvolver sua própria linguagem porque queria uma linguagem
de script que fosse mais poderosa que Perl e mais orientada a objetos que Phyton.
O desenvolvimento do Ruby começou no dia 24 de fevereiro de 1993, e o
primeiro “hello world” programado em Ruby rodou no verão do mesmo ano. A primeira
versão alpha da linguagem foi liberada em dezembro de 1994.
Ruby se tornou reconhecida no meio especializado desde que Dave Thomas e
Andrew Hunt, conhecidos como "Programadores Pragmáticos", adotou-a como uma de
suas linguagens preferidas e acabou por escrever um dos mais completos livros sobre a
4
linguagem, o Programming Ruby. Com o advento desta publicação, a linguagem passou
a contar com uma boa fonte de iniciação e referência em inglês, aumentando
conseqüentemente o número de adeptos da linguagem no Ocidente.
O nome "Ruby", foi decidido durante uma sessão de bate-papo online entre
Matsumoto (Matz) e Keiju Ishitsuka em 24 de fevereiro de 1993, antes que qualquer
linha de código tivesse sido escrita para a linguagem.[11] Inicialmente foram propostos
dois nomes: "Coral" e "Ruby", sendo esse último nome proposto escolhido mais tarde
por Matz em um e-mail para Ishitsuka.[12] Mais tarde Matz descobriu que Pearl é a
pedra preciosa que simboliza o mês de Junho e Ruby é a pedra que simboliza Julho,
então ele concluiu que é um nome apropriado para uma linguagem que surge depois do
Perl
1.2 Características da linguagem Ruby
Todas as variáveis são objetos, onde até os "tipos primitivos" (tais como
inteiro, real, entre outros) são classes;
Métodos de geração de código em tempo real, como os "attribute
accessors";
Através do RubyGems, é possível instalar e atualizar bibliotecas com
uma linha de comando, de maneira similar ao APT do Debian Linux;
5
Code blocks (blocos de código) passados como parâmetros para
métodos; permite a criação de closures;
Mixins, uma forma de emular a herança múltipla;
Tipagem dinâmica, mas forte. Isso significa que todas as variáveis
devem ter um tipo (fazer parte de uma classe), mas a classe pode ser
alterada dinamicamente;
Ruby está disponível para diversas plataformas, como Microsoft
Windows, Linux, Solaris e Mac OS X, além de também ser executável
em cima da máquina virtual do Java (através doJRuby) e haver um
projeto para ser executável em cima da máquina virtual Microsoft .NET,
o IronRuby.
1.3 O que são Ruby Gems ?
Ruby gems são bibliotecas e frameworks tais como : hibernate , spring e struts o
são para Java. A diferença entre as Ruby Gems e os tradicionais frameworks Java é que
as ruby Gems podem ser instaladas por um comando simples, tal como o : "apt-get
install" dos debian Linux.
Mais adiante será demonstrada a instalação do ruby gem, mas por hora vale
lembrar que em uma maquina com o Rubygem corretamente instalado , basta fazer o
seguinte comando para instalar uma biblioteca ou framework :
6
"gem install Nomedabiblioteca".
Existem hoje nos repositórios do rails , mais de 12 mil gems disponíveis para as
mais diversas necessidades. Além das gems existem ainda as bibliotecas que não
chegam a ir para os repositórios por serem muito recentes ou por serem muito simples ,
essas bibliotecas podem ser baixadas e utilizadas gratuitamente de portais tais como :
Ruby Forge e Ruby Application Archive (RAA), um exemplo dessas bibliotecas é o
Active Scaffold que será demonstrada mais adiante para desenvolver cadastros.
1.4 O que é MVC ?
Essa é uma sigla comum para a programação web e entender sua definição é
fundamental para entender o que é o rails.
MVC significa Model-View-Controler ou modelo-visão-controlador em
português , trata-se de uma arquitetura para programação de sistemas Web baseada em
três componentes principais : Model , View e Controller.
Ao contrário dos tradicionais sistemas onde o programador da comandos Select ,
insert ou update na própria página que o internauta vê , e ainda a própria página decide
qual será a próxima página a ser exibida (fluxo do sistema); os sistemas baseados no
MVC tentam organizar as coisas colocando cada coisa no seu devido lugar , visando
aumentar a performance , a segurança e manutenção do sistema.
No MVC cada um dos componentes tem um papel claro e definido no sistema
web:
7
Model: O Model reprensenta a informação (dados) da aplicação e as regras pra
manipular esses dados. No caso do Rails (o meta-framework que usaremos com o ruby),
o model é primeiramente usado pra gerenciar as regras de interação com uma base de
dados correspondente. Na maioria dos casos uma tabela do banco de dados terá um
modelo correspondente na aplicação. As regras de negócios da aplicação ficarão
concentradas no Model.
View: é o componente responsável pela interface da aplicação para o usuário.
No rails, as views costumam ser arquivos HTML com código ruby embutido que
executam tarefas relativas somente à apresentação dos dados.
Controller : é o componente que recebe a requisição do usuário (GET, POST ,
PUT , DELETE) trata a requisição (persiste os dados no banco , valida login) e por
último redireciona o usuário para a página adequada. Faz a ligação entre o model e o
view.
O controller é o componente mais complexo e tende a ser o mais longo (maior
número de linhas de código) dentre todos os componentes do MVC.
Para um exemplo simples de controle de locadoras:
- O Usuário faz uma requisição de Get ao controlador „listafilmes‟ digitando no
browser (ou cliando em um link) : www.locadora.com.br/listafilmes
O controlador „listafilmes‟:
- recebe a requisição
- faz um select no banco
- Carrega uma coleção na requisição com os filmes selecionados
8
- Invoca a visão (view) „listafilmes.html.erb‟
A visão listafilmes.html.erb somente exibe na tela o conteúdo da coleção de
filmes carregada pelo controlador.
Ao ver a página o usuário pode clicar em algum link e então mandar outra
requisição para algum controlador e assim recomeçar o ciclo.
1.5 O que é Rails?
Rails é o mais popular framework de MVC do ruby, e é o responsável pela
expansão da linguagem ruby no mercado.
Rails é uma gem desenvolvida utilizando a linguagem ruby que tem como
finalidade facilitar o desenvolvimento de sistemas Web baseados na arquitetura MVC.
Tornou-se muito popular por ser extremamente produtiva ao utilizar conceitos como
DRY (Don't repeat yourself) e COC (Convention Over Configuration).
Rails é produtivo por se basear em padrões e por isso dispensar os XMLs e/ou
annotations.
Ou seja, o Rails é apenas um framework MVC criado na linguagem ruby , por
isso utiliza-se o termo programar em ruby on rails (programar no ruby sobre o rails).
9
2 A LINGUAGEM RUBY
2.1 Instalando o ruby
Uma das grandes dificuldades do ruby on rails é possuir série vários elementos a
serem instaladas, e isso demanda um bom tempo de trabalho.
Como ambiente de desenvolvimento web será utilizado o Linux Ubuntu 10.04
LTS (Lucid Lynx) , rails na versão 2.3.2 e banco de dados MySQL. E para
desenvolvimento Desktop será utilizado Windows XP SP2 , Delphi 7 e banco de dados
Firebird.
No Linux, preparando o ambiente para o Ruby On Rails:
Para instalar o ruby através do console Shell, é necessário executar o comando :
sudo apt-get install ruby
Para instalar o interpretador de Ruby, também no console Shell, através do
comando :
sudo apt-get install irb
Para testar se o Ruby está instalado corretamente (via shell), é executado o
comando :
irb
Como resultado deve ser mostrado:
irb(main):001:0>
10
Para sair ultilize o comando quit .
2.2 Programando em ruby
Antes de iniciar a programação em ruby, alguns conceitos da linguagem:
O condicional em ruby funciona do seguinte modo :
if condição
comando
if condição
comando A
else
comando b
#ou para blocos
if condição
comando1
comando2
end
if condição
comandoA1
comandoA2
else
comandob1
comandob2
end
11
É possível ainda:
comando if condição (só executa o comando se a condição for verdadeira)
comando unless condição (Executa somente se a condição for falsa)
Os operadores de comparação são:
== igual
> maior
< menor
!= diferente
2.2.1 As convenções do Ruby
O Ruby tem uma série de convenções para nomes de métodos, seguem as
principais :
#indica se uma string esta vazia
'alguma string'.empty?
#todo método que retorna booleano deve terminar com ?
cliente.is_restrito?
#todo método que modifica efetivamente uma classe deve terminar com !
cliente.restringe!
12
# método equals deve por convenção devem ser ==
def ==(pessoa)
return @nome == pessoa.nome
end
p1 = pessoa.new
p2 = pessoa.new
puts p1 == p2 #exemplo de utilização do método equals
2.2.2 Os Arrays
Ao contrário de algumas linguagens, o array é efetivamente utilizado em Ruby.
Seguem as principais características dos arrays Ruby :
a = Array.new
#equivalente a
a = []
#Métodos de fazer uma atribuição (append) em um array
a << 2
a[1] = 3 #outro método de atribuição
a = [2,5,'a']
#para testar:
puts a[0] # será impresso „2‟
13
2.2.3 Retorno de métodos
Uma novidade no ruby é que um método pode retornar N parâmetros
def MetodoDuploRet
return 2,7
end
puts MetodoDuploRet
a = MetodoDuploRet
puts a
b,c = MetodoDuploRet
puts b
puts c
2.2.4 Criando classes no ruby
Seguem abaixo alguns exemplos de como trabalhar com classes utilizando o
ruby:
#toda a classe é uma instância de class
#logo uma classe é definida da seguinte maneira
Pessoa = Class.new do
def say
puts 'hello'
end
end
p = Pessoa.new
p.say
14
Pessoa2 = Class.new
#Método fora de qualquer classe vai para Object
def say2
puts 'p2'
end
#Pessoa2.say2
self.say2
self.class
Object.say2
Exemplo de classe completa com fields , getters e setters :
class Pessoa
#não precisa declarar o field
#setter
def nome=(valor)
@nome = valor
end
#getter
def nome
@nome
end
#jeito rápido de criar getter
attr_reader :cpf
#jeito rápido de criar setter
attr_writer :cpf
#maneira mais rápida ainda de criar getter e setter
attr_accessor :idade
15
#construtor
def initialize (valor)
@nome = valor
end
#método estático class method
def self.metodo_estatico
puts 'isto é um método estático'
end
end
2.2.5 Herança em Ruby
class Animal
def come
puts 'comendo'
end
private
def metodo_privado
puts 'este é privado'
end
end
class Peixe < Animal
end
p = Peixe.new
p.come
p.metodo_privado # Cuidado. Aqui daria erro de execução porque o método é
privado
16
2.2.6 Polimorfismo e interfaces
#duck typing
#não precisa de interface
#ruby não tem interface
class PatoEstranho
def faz_quack
puts 'queck'
end
end
class PatoNormal
def faz_quack
puts 'quack'
end
end
class CriadorDePato
def castiga(pato)
pato.faz_quack
end
end
pe = PatoEstranho.new
pn = PatoNormal.new
c = CriadorDePato.new
c.castiga pe
c.castiga pn
17
2.2.7 Os Hashes
Outra estrutura de coleção muito importante no ruby e utilizada no rails são os
hashes (semelhantes ao Map do Java).
Seguem exemplos de utilização de hashes :
class Carro
attr_accessor :dono
def initialize (nomedono)
@dono = nomedono
end
end
c1 = Carro.new "Ricardo"
c2 = Carro.new "mariana"
#criando um hash
detran = {:"ABC1122" => c1,
:"EBE5774" => c2}
puts detran[:"EBE5774"].dono
def transfere(args)
puts "transferindo #{args[:valor]} para a conta #{args[:n]}"
end
transfere({:valor => 100, :n => 234 })
#mais simples
transfere :valor => 100, :n => 234
18
2.2.8 Como funciona o CompareTo
#No ruby por convenção o compareTo é <=>
#Exemplo de utilização de compareTo :
class Cachorro
attr_accessor :peso
def <=> (outro)
return 0 if peso == outro.peso
return 1 if peso > outro.peso
return -1 if peso < outro.peso
end
end
a.equal? b #o mesmo que equals ==
a.eqr? #o mesmo que igual pelo hashcode
2.2.9 Metaprogramação
No Ruby é possível alterar ou adicionar métodos em tempo de execução porque
todo código Ruby é executado – não há separação entre fases de compilação e runtime,
cada linha de código é executado contra um self particular.
class Aluno
end
19
class Professor
def ensina aluno
def aluno.responde # aqui é possível adicionar um método à classe
aluno
puts 'agora eu sei tudo'
end
end
end
a = Aluno.new
#a.responde
p = Professor.new
p.ensina a
a.responde
#exemplo de metaprogramação - adicionar um método em tempo de execução
class Carro
end
class Oficina
def turbina(carro)
def carro.turbo
puts 'turbo ligado'
end
end
end
c = Carro.new
#c.turbo
o = Oficina.new
o.turbina c
c.turbo
20
2.2.10 Closures
O Ruby também permite passar métodos como parâmetros:
#exemplo básico de closure
def metodo
puts "linha 1"
yield #aqui vai entrar o código do bloco que vier como parâmetro
end
metodo do # isso é o mesmo que chamar metodo passando um trecho de código
#como parâmetro
puts "linha 2" #isso é parâmetro
end
#exemplo mais complexo de closure
def metodo2
puts "linha B1"
yield "ricardo" , "adv" # O código que vier aqui vai receber estes dois
parâmetros
yield("facilita" , "facilitador") # Também pode se usar parênteses
end
# como funciona:
# o & permite passar um bloco como param para utilizar o call
# o yield e o método call são equivalentes
# embora o call fique mais claro a convenção é utilizar o yield
21
def met (&metodo)
metodo.call # o mesmo que yield
end
met do
puts 'teste'
end
# o mesmo que o anterior mas utilizando uma variável para guardar o bloco
#aqui não é preciso do & pois passa uma variável com o bloco
def met2 (met)
met.call
end
#atribuindo um bloco a uma variável
bloco = lambda {
puts 'teste2'
}
bloco.call # execução para teste
met2(bloco) # passando por parâmetro
22
3 RAILS
Conforme já foi mostrado antes, o Rails, é um framework desenvolvido em
Ruby e de código aberto assim como Ruby. Leva em sua arquitetura o design pattern
"MVC" (Model-View-Controller). O modelo MVC oferece vantagens significativas no
desenvolvimento de aplicativos, através da separação das camadas, possibilitando
implementar com maior facilidade e clareza questões programáticas importantes como a
persistência de dados, controle de segurança, comunicação em rede e fluxo de
visualização.
O Rails pode ser considerado um "meta-framework" porque é uma junção
de vários componentes:
Active Record
O Active Record é uma camada de mapeamento objeto-relacional (object-
relational mapping layer), responsável pela interoperabilidade entre a aplicação e o
banco de dados e pela abstração dos dados.
Action Pack
Compreende o Action View (geração de visualização de usuário, como HTML,
XML, JavaScript, entre outros) e o Action Controller (controle de fluxo de negócio).
Action Mailer
O Action Mailer é um framework responsável pelo serviço de entrega e até
mesmo de recebimento de e-mails. É relativamente pequeno e simples, porém poderoso
23
e capaz de realizar diversas operações apenas com chamadas de entrega de
correspondência.
Active Support
Active Support é uma coleção de várias classes e extensões de bibliotecas
padrões, que foram consideradas úteis para aplicações em Ruby on Rails.
Action WebServices
Provê uma maneira de publicar APIs interoperáveis com o Rails, sem a
necessidade de perder tempo dentro de especificações de protocolo. Implementa WSDL
e SOAP.
O Action Web Service não estará mais presente na versão 2.0 no Rails, visto que
o mesmo está voltando-se para a utilização do modelo REST. Mesmo assim, aos ainda
interessados em utilizá-lo, será possível fazê-lo através da instalação de um plugin.
3.1 Começando a usar o rails
A instalação do Rails é feita da seguinte forma:
Primeiro é necessário instalar o Ri (testador do ruby) e o rdoc (gerador de
documentação do ruby semelhante ao Javadoc do Java)
No Console digitando:
sudo apt-get install rdoc ri
24
Depois instalando o programa que gerencia as gems (lembram das gems) do
ruby. Este não vale a pena instalar via apt-get install porque a versão nos repositórios
debian tem alguns bugs.
No Console digitando:
cd /usr/local
wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
tar xvzf rubygems-1.3.5.tgz
cd rubygems-1.3.5/
sudo ruby setup.rb
Feito isso o comando gem1.8 gera em qualquer pasta da máquina o help do
Gem:
ricardo@programacao1:/usr/local$ gem1.8
Gerando a seguinte documentação:
RubyGems is a sophisticated package manager for Ruby. This is a
basic help message containing pointers to more information.
Usage:
gem -h/--help
gem -v/--version
gem command [arguments...] [options...]
25
Examples:
gem install rake
gem list --local
gem build package.gemspec
gem help install
Further help:
gem help commands list all 'gem' commands
gem help examples show some examples of usage
gem help platforms show information about platforms
gem help <COMMAND> show help on COMMAND
(e.g. 'gem help install')
Further information:
http://rubygems.rubyforge.org
para não precisar digitar „gem1.8‟ , cria-se um link simbólico:
sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
Agora o comando „gem‟ deve funcionar igual a „gem1.8‟.
Embora pareça, o rubygems não está instalado ainda, faltam bibliotecas que ele
utiliza em C++ .
No terminal execute os comandos:
sudo apt-get install libopenssl-ruby sqlite3 build-essential libsqlite3-dev
libmysqlclient15-dev ruby-dev ruby1.8-dev
26
Para todos os exemplos a seguir, será utilizado o mysql , então é preciso instalar
caso ainda não esteja (pelo terminal):
sudo apt-get install mysql-server
E um client para mexer no mysql:
sudo apt-get install mysql-query-browser
Agora instalando as gems necessárias ao rails:
sudo gem install rails –version “2.3.2”
sudo gem install mongrel
sudo gem install mysql
Agora executando um comando que lista as gems instaladas :
gem list --local
A lista retornada deve ser :
*** LOCAL GEMS ***
actionmailer (2.3.2)
actionpack (2.3.2)
activerecord (2.3.2)
activeresource (2.3.2)
activesupport (2.3.2)
cgi_multipart_eof_fix (2.5.0)
daemons (1.1.0)
27
fastthread (1.0.7)
gem_plugin (0.2.3)
mongrel (1.1.5)
mysql (2.8.1)
rails (2.3.2)
rake (0.8.7)
O rails já está instalado, agora é necessário uma IDE.
Uma muito utilizada para o rails, atualmente, é o aptana:
Para instalar é necessário baixar o tar.gz de acordo com a arquitetura do
ambiente em http://www.aptana.com/radrails/download/
Copiando e descompactando a pasta em /usr/local, depois executando o
comando :
sudo ./Aptanastudio # o aptana será aberto.
Obs: Antes de executar o aptana é necessário ter o java instalado.
3.2 A primeira aplicação no rails
Com o ambiente instalado e configurado, para iniciar o desenvolvimento de um
projeto pelo console Shell, são executados (para criar as pastas do projeto):
cd /home
mkdir fontes
mkdir rails
cd /home/fontes/rails
28
Agora para criar um projeto cujo banco de dados é mysql (via Shell):
rails agenda -d mysql
Feito isso o rails vai criar uma pasta „agenda‟ com uma determinada estrutura de
diretórios dentro. A finalidade dos diretórios está descrita abaixo:
Readme – arquivo com instruções de uso;
Rakefile – script de construção;
app/ – Dentro dessa pasta estão os arquivos da estrutura MVC – (Model, View e
Controller);
components/ – componentes reutilizáveis;
config/ – parâmetros de configurações tanto do projeto quanto do banco de
dados;
db/ – Informações sobre o esquema e as migrations geradas para modificar o
banco de dados;
doc/ – Documentação auto gerada, utilizando o Rdoc,
lib/ – Código compartilhado códigos que não podemos adicionar a uma um
modelo, view ou controller, algo como um gerador de arquivos pdf.
log/ – documentos de log produzidos pelo seu aplicativo;
public/ – Diretório acessível pela Web. É a pasta onde o HTTP server utiliza pra
rodar o aplicativo;
29
script/ – Scripts utilitários, onde estão os programas utilizados pelos
desenvolvedores Rails;
test/ – Utilitários de testes, onde são escritos os teste funcionais, testes de
integração, fixtures e simulações;
tmp/ – Arquivos temporários utilizados e gerados em tempo de execução do seu
aplicativo;
vendor/ – Código importado onde são colocados os plugins utilizados pela
aplicação, código de terceiros.
As pastas app/ e db/ é onde fica quase toda a aplicação, são as pastas mais
alteradas em um projeto.
Todo projeto rails tem alguns scripts padrões na sua pasta raiz , então ao digitar
(no prompt de comandos):
cd agenda
Entrará na raiz da aplicação e podem ser utilizados os seguintes scripts (esses
scripts são executados no shell do Linux dentro do diretório do projeto) :
script/server start - Inicia a aplicação no browser (põe no ar), para parar basta
utilizar Ctrl +C.
rake db:create:all - cria as bases de dados do projeto , as bases são definidas no
arquivo config/database.yml
rake db:migrate - atualiza a estrutura do banco com as tabelas criadas no projeto
30
rake db:migrate:down -Version xxxx - Volta o banco de dados para uma versão
específica.
Script/generate artefato* nome_do_artefato - gera diversos artefatos* , são
alguns deles :
Migration - Arquivo que modifica os bancos de dados da aplicação.
Model - Gera automaticamente uma migration para criar o model em questão e
um model no sistema. Models são classes do modelo de negócio ( Clientes , Produtos e
etc...)
Controller - Gera um controlador automaticamente.
3.2.1 O plugin ActiveScaffold
O Active Scaffold é um dos plugins responsáveis pelo ganho de produtividade
que o RubyOnRails oferece, e que o torna uma opção interessante para o
desenvolvimento web.
O active scaffold pode ser instalado com um comando na pasta do projeto rails,
mas antes (apenas na primeira vez) é necessário instalar uma dependência, o git-core :
apt-get install git-core
Agora, com o git-core instalado, o seguinte comando instala o plugin do Active
Scaffold no projeto:
script/plugin install git://github.com/activescaffold/active_scaffold.git -r rails-2.3
31
Depois de instalado , prepara-se a aplicação para utilizá-lo , para isto é
necessário tomar os seguintes passos :
Abrir o Aptana (via shell script, para abrir como root) e adicionar o projeto
nele:
no prompt de comandos, no diretório onde se encontra o Aptana, executa-se o
comando
sudo ./AptanaRadRails
Após aberto a IDE, para adicionar um projeto, em
File -> New -> Rails Project , selecione a opção „Create project from existing
source‟ e busque a pasta onde o projeto foi criado anteriormente via shell (pelo
comando „rails agenda -d mysql‟)
Preparar todas as views para que elas importem o CSS e Javascript
necessário para o ActiveScaffold, para isso criam-se um template de
aplicação na pasta app/view/layouts e um template de CSS na pasta
public/stylesheets:
Na pasta app/view/layouts cria-se o arquivo application.html.erb com o seguinte
conteúdo:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Contatos</title>
32
<%= javascript_include_tag :defaults %>
<%= active_scaffold_includes %>
<%= stylesheet_link_tag 'default.css' %>
</head>
<body>
</body>
</html>
E na pasta public/stylesheets cria-se o arquivo default.css com o seguinte
conteúdo (esse conteúdo é apenas sugestivo, é o layout padrão da aplicação e pode ser
editado conforme a necessidade do projeto):
a {
text-decoration: none;
color:#AAAAAA;
font-weight:bold;
}
a:hover {
color: #AFD0F5;
}
33
Agora se adiciona o active scaffold ao controlador do modelo que será
criado o cadastro:
Por exemplo, ao criar um cadastro de contatos para o projeto da Agenda:
- como será o primeiro cadastro, é necessário criar o banco de dados, mas antes é
preciso definir a senha do mysql no projeto. Isso é feito dentro do arquivo
/config/database.yml, no campo password conforme o exemplo (via aptana):
development:
adapter: mysql
encoding: utf8
reconnect: false
database: agenda_development
pool: 5
username: root
password: 123456
socket: /var/run/mysqld/mysqld.sock
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: mysql
encoding: utf8
reconnect: false
database: agenda_test
pool: 5
username: root
password: 123456
socket: /var/run/mysqld/mysqld.sock
production:
adapter: mysql
34
encoding: utf8
reconnect: false
database: agenda_production
pool: 5
username: root
password: 123456
socket: /var/run/mysqld/mysqld.sock
Aqui a aplicação já está configurada para utilizar o ActiveScaffold.
Agora se cria o banco de dados da aplicação (via shell script):
rake db:create:all
Cria-se o modelo (via shell script:
script/generate model contato nome:string idade:integer fone:string endereco:string
Cria-se a migration, que criará a tabela no banco de dados (via shell script):
rake db:migrate
Cria-se o controller (via shell script):
script/generate controller contatos #aqui é necessário acrescentar a letra „s‟ no
# final (por padrão do rails)
No controller criado, é necessário adicionar o seguinte código, dentro da classe
já existente (via aptana) :
obs: o controller fica na pasta app/controllers e, nesse caso, chama
contatos_controller.rb
active_scaffold :contato do | config |
35
end
Para testar basta acessar a seguinte URL (pelo browser):
http://localhost:3000/contatos/
Porém alguns ajustes ainda podem ser feito, como:
Definir o idioma da aplicação para português.
Incluir o arquivo de localização para o Brasil do ActiveScaffold.
Encaminhar o chamado de rota do controller para o ActiveScaffold para resolver
o erro na ordenação.
Para realizar esses ajustes:
Para definir o idioma é necessário abrir o arquivo /config/environment.rb e
adicionar a linha :
config.i18n.default_locale = :pt
Agora para adicionar o arquivo de português na aplicação basta salvar um
arquivo chamado pt.yml na pasta /config/locales com o seguinte conteúdo:
pt:
# formatos de data e hora
active_scaffold:
add: "Add"
add_existing: "Associar existente"
are_you_sure: "Você tem certeza?"
cancel: "Cancelar"
click_to_edit: "Click para editar"
close: "Fechar"
create: "Inserir"
create_model: "Inserir {{model}}"
36
create_another: "Inserir Outro"
created_model: "{{model}} Inserido"
create_new: "Inserir Novo"
customize: "Customizar"
delete: "Deletar"
deleted_model: "{{model}} Deletado"
delimiter: "Delimiter"
download: "Download"
edit: "Editar"
export: "Export"
filtered: "(Filtrado)"
found: "Encontrados"
hide: "Ocultar"
live_search: "Localizar"
loading…: "Carregando…"
nested_for_model: "{{nested_model}} for {{parent_model}}"
next: "Próximo"
no_entries: "Nenhum registro encontrado"
omit_header: "Ocultar cabeçalho"
options: "Opções"
pdf: "PDF"
previous: "Anterior"
print: "Imprimir"
refresh: "Atualizar"
remove: "Remover"
remove_file: "Remover ou Substituir arquivo"
replace_with_new: "Substituir com o novo"
revisions_for_model: "Revisions for {{model}}"
reset: "Limpar"
saving…: "Salvando…"
search: "Localizar"
search_terms: "Buscar por"
_select_: "-"
show: "Exibir"
show_model: "Exibindo {{model}}"
_to_ : " to "
update: "Alterar"
update_model: "Alterando {{model}}"
udated_model: "Updated {{model}}"
37
percentage_example: "Ex. 10%"
usa_phone_example: "Ex. 111-333-4444"
usa_money_example: "Ex. 1.333"
usa_zip_example: "Ex. 88888-333"
ssn_example: "Ex. 555-22-3333"
# error_messages
internal_error: "Request Failed (code 500, Internal Error)"
version_inconsistency: "Version inconsistency - this record has been modified since you
started editing it."
date:
formats:
default: "%d/%m/%Y"
short: "%d de %B"
long: "%d de %B de %Y"
day_names: [Domingo, Segunda, Terça, Quarta, Quinta, Sexta, Sábado]
abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, Sáb]
month_names: [~, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto,
Setembro, Outubro, Novembro, Dezembro]
abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez]
order: [ :day, :month, :year ]
time:
formats:
default: "%A, %d de %B de %Y, %H:%M hs"
short: "%d/%m, %H:%M hs"
long: "%A, %d de %B de %Y, %H:%M hs"
am: ''
pm: ''
# date helper distanci em palavras
datetime:
distance_in_words:
half_a_minute: 'meio minuto'
less_than_x_seconds:
38
one: 'menos de 1 segundo'
other: 'menos de {{count}} segundos'
x_seconds:
one: '1 segundo'
other: '{{count}} segundos'
less_than_x_minutes:
one: 'menos de um minuto'
other: 'menos de {{count}} minutos'
x_minutes:
one: '1 minuto'
other: '{{count}} minutos'
about_x_hours:
one: 'aproximadamente 1 hora'
other: 'aproximadamente {{count}} horas'
x_days:
one: '1 dia'
other: '{{count}} dias'
about_x_months:
one: 'aproximadamente 1 mês'
other: 'aproximadamente {{count}} meses'
x_months:
one: '1 mês'
other: '{{count}} meses'
about_x_years:
one: 'aproximadamente 1 ano'
other: 'aproximadamente {{count}} anos'
over_x_years:
one: 'mais de 1 ano'
other: 'mais de {{count}} anos'
prompts:
39
year: "Ano"
month: "Mês"
day: "Dia"
hour: "Hora"
minute: "Minuto"
second: "Segundos"
# numeros
number:
format:
precision: 3
separator: ','
delimiter: '.'
currency:
format:
unit: 'R$'
precision: 2
format: '%u %n'
separator: ','
delimiter: '.'
percentage:
format:
delimiter: '.'
precision:
format:
delimiter: '.'
human:
format:
precision: 1
delimiter: '.'
storage_units:
format: "%n %u"
units:
byte:
one: "Byte"
other: "Bytes"
kb: "KB"
mb: "MB"
gb: "GB"
40
tb: "TB"
# Used in array.to_sentence.
support:
array:
words_connector: ", "
two_words_connector: " e "
last_word_connector: " e "
# Active Record
activerecord:
errors:
template:
header:
one: "Não foi possível gravar {{model}}: 1 erro"
other: "Não foi possível gravar {{model}}: {{count}} erros."
body: "Por favor, verifique o(s) seguinte(s) campo(s):"
messages:
inclusion: "não está incluído na lista"
exclusion: "não está disponível"
invalid: "não é válido"
confirmation: "não está de acordo com a confirmação"
accepted: "deve ser aceito"
empty: "não pode ficar vazio"
blank: "não pode ficar em branco"
too_long: "é muito longo (máximo: {{count}} caracteres)"
too_short: "é muito curto (mínimo: {{count}} caracteres)"
wrong_length: "não possui o tamanho esperado ({{count}} caracteres)"
taken: "já está em uso"
not_a_number: "não é um número"
greater_than: "deve ser maior do que {{count}}"
greater_than_or_equal_to: "deve ser maior ou igual a {{count}}"
equal_to: "deve ser igual a {{count}}"
less_than: "deve ser menor do que {{count}}"
less_than_or_equal_to: "deve ser menor ou igual a {{count}}"
odd: "deve ser ímpar"
even: "deve ser par"
41
Resolvido o problema idiomático , é necessário criar uma rota para a função
“procurar” funcionar. Para isso, no arquivo /config/routes.rb adiciona-se no começo
do arquivo, porém após a linha „ActionController::Routing::Routes.draw do |map|‟, o
seguinte:
map.resources :contatos, :active_scaffold => true
Para testar novamente, acesse a url :
http://localhost:3000/contatos/
Para definir a ordem das colunas do grid e quais colunas aparecerão é necessário
definir no controlador uma matriz com as colunas e a ordem que serão exibidas.
Abrindo o arquivo contatos_controller.rb, adicione o seguinte :
active_scaffold :contato do | config |
config.columns = [:nome :endereco :fone :idade ]
end
Para alterar o label dos campos que são exibidos ao usuário e colocar uma
paginação no grid, também no controller, adiciona-se o código:
active_scaffold :contato do | config |
config.list.columns = [:nome, :endereco, :fone, :idade ]
config.list.per_page = 5 #adiciona paginação a cada 5 registros
config.columns[:nome].label = "Nome"
config.columns[:endereco].label = "Endereço"
config.columns[:fone].label = "Telefone"
config.columns[:idade].label = "Idade"
end
42
Na edição do cadastro, para não aparecer uma descrição estranha como por
exemplo Alterando #<Contato:0x7f1a428d9cb8> , é necessário adicionar o seguinte
código no model (colocar o código via aptana dentro da classe „Contato‟, no model
„contato.rb‟ da pasta models):
def to_s
nome
end
Feito isso os cadastros ficam como os do exemplo a seguir:
Figura 1 - Tela inicial do cadastro de Contatos
Figura 2 - A consulta é feita em qualquer campo do cadastro
43
Figura 3 - Tela de inclusão
Figura 4 - tela de edição
44
Figura 5 - excluindo um registro
45
4 CRIAÇÃO DE CADASTROS COM RAILS E ACTIVE
SCAFFOLD (CRUD)
4.1 Demonstração do desenvolvimento Ruby X Delphi
Para demonstrar a produtividade do RubyOnRails na criação de sistemas
baseados em telas CRUD será feito um comparativo com o desenvolvimento em delphi.
Os requisitos serão os seguintes:
Criar cadastros com as funções de incluir, consultar, alterar e excluir registros.
(Clientes , produtos e vendedores).
Em RubyOnRais, com o plugin ActiveScaffold:
Antes de definir os passos para criar os cadastros vale lembrar que a qualquer
momento pode ser iniciada a aplicação com o comando shell:
script/server start
E então ela poderá ser acessada na url http://localhost:3000/Nome_controller ,
onde Nome_controller é o nome de algum controller da aplicação. Por exemplo, para
acessar o cadastro de clientes:
http://localhost:3000/clientes
São tomados os seguintes passos:
Criar o projeto
46
No shell:
su #para trabalhar logado como root
cd /home/fontes/rails
rails vendas -d mysql
Adicionar o projeto no Aptana
Para abrir o aptana como root:
No shell, mas em outra instância do terminal (porque ela ficará presa
durante a execução do aptana):
su #para trabalhar logado como root
cd /usr/local/Aptana\ RadRails/ #diretório do Aptana
./AptanaRadRails
Adicionar o projeto na IDE
Adicionar o plugin do ActiveScaffold ao projeto
No shell ():
cd /home/fontes/rails/vendas/ #para entrar no diretório do projeto
script/plugin install git://github.com/activescaffold/active_scaffold.git -r
rails-2.3
47
Criar os templates de view e css (no Aptana):
Na pasta app/views/layouts criar o arquivo „application.html.erb‟ com o
conteúdo:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Vendas</title>
<%= javascript_include_tag :defaults %>
<%= active_scaffold_includes %>
<%= stylesheet_link_tag 'default.css' %>
</head>
<body>
<%= yield %>
</body>
</html>
Na pasta public/stylesheets criar o arquivo „default.css‟ com o conteúdo:
a {
text-decoration: none;
color:#AAAAAA;
font-weight:bold;
}
a:hover {
color: #AFD0F5;
}
Definir a senha do MySql (no Aptana)
No arquivo config/database.yml colocar a senha no campo „password‟
48
# MySQL. Versions 4.1 and 5.0 are recommended.
#
# Install the MySQL driver:
# gem install mysql
# On Mac OS X:
# sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
# On Mac OS X Leopard:
# sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-
config=/usr/local/mysql/bin/mysql_config
# This sets the ARCHFLAGS environment variable to your native architecture
# On Windows:
# gem install mysql
# Choose the win32 build.
# Install MySQL and put its /bin directory on your path.
#
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
adapter: mysql
encoding: utf8
reconnect: false
database: vendas_development
pool: 5
username: root
password: 123456
socket: /var/run/mysqld/mysqld.sock
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: mysql
encoding: utf8
reconnect: false
database: vendas_test
pool: 5
username: root
password: 123456
socket: /var/run/mysqld/mysqld.sock
49
production:
adapter: mysql
encoding: utf8
reconnect: false
database: vendas_production
pool: 5
username: root
password: 123456
socket: /var/run/mysqld/mysqld.sock
Criar o banco de dados
No shell:
rake db:create:all
Ajustar o idioma no projeto(no aptana)
no arquivo /config/environment.rb , adicionar a linha:
config.i18n.default_locale = :pt
criar um arquivo chamado pt.yml na pasta /config/locales com o
conteúdo:
pt:
# formatos de data e hora
active_scaffold:
add: "Add"
add_existing: "Associar existente"
are_you_sure: "Você tem certeza?"
cancel: "Cancelar"
click_to_edit: "Click para editar"
close: "Fechar"
create: "Inserir"
create_model: "Inserir {{model}}"
50
create_another: "Inserir Outro"
created_model: "{{model}} Inserido"
create_new: "Inserir Novo"
customize: "Customizar"
delete: "Deletar"
deleted_model: "{{model}} Deletado"
delimiter: "Delimiter"
download: "Download"
edit: "Editar"
export: "Export"
filtered: "(Filtrado)"
found: "Encontrados"
hide: "Ocultar"
live_search: "Localizar"
loading…: "Carregando…"
nested_for_model: "{{nested_model}} for {{parent_model}}"
next: "Próximo"
no_entries: "Nenhum registro encontrado"
omit_header: "Ocultar cabeçalho"
options: "Opções"
pdf: "PDF"
previous: "Anterior"
print: "Imprimir"
refresh: "Atualizar"
remove: "Remover"
remove_file: "Remover ou Substituir arquivo"
replace_with_new: "Substituir com o novo"
revisions_for_model: "Revisions for {{model}}"
reset: "Limpar"
saving…: "Salvando…"
search: "Localizar"
search_terms: "Buscar por"
_select_: "-"
show: "Exibir"
show_model: "Exibindo {{model}}"
_to_ : " to "
update: "Alterar"
update_model: "Alterando {{model}}"
udated_model: "Updated {{model}}"
51
percentage_example: "Ex. 10%"
usa_phone_example: "Ex. 111-333-4444"
usa_money_example: "Ex. 1.333"
usa_zip_example: "Ex. 88888-333"
ssn_example: "Ex. 555-22-3333"
# error_messages
internal_error: "Request Failed (code 500, Internal Error)"
version_inconsistency: "Version inconsistency - this record has been modified
since you started editing it."
date:
formats:
default: "%d/%m/%Y"
short: "%d de %B"
long: "%d de %B de %Y"
day_names: [Domingo, Segunda, Terça, Quarta, Quinta, Sexta, Sábado]
abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, Sáb]
month_names: [~, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho,
Agosto, Setembro, Outubro, Novembro, Dezembro]
abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov,
Dez]
order: [ :day, :month, :year ]
time:
formats:
default: "%A, %d de %B de %Y, %H:%M hs"
short: "%d/%m, %H:%M hs"
long: "%A, %d de %B de %Y, %H:%M hs"
am: ''
pm: ''
# date helper distanci em palavras
datetime:
distance_in_words:
half_a_minute: 'meio minuto'
52
less_than_x_seconds:
one: 'menos de 1 segundo'
other: 'menos de {{count}} segundos'
x_seconds:
one: '1 segundo'
other: '{{count}} segundos'
less_than_x_minutes:
one: 'menos de um minuto'
other: 'menos de {{count}} minutos'
x_minutes:
one: '1 minuto'
other: '{{count}} minutos'
about_x_hours:
one: 'aproximadamente 1 hora'
other: 'aproximadamente {{count}} horas'
x_days:
one: '1 dia'
other: '{{count}} dias'
about_x_months:
one: 'aproximadamente 1 mês'
other: 'aproximadamente {{count}} meses'
x_months:
one: '1 mês'
other: '{{count}} meses'
about_x_years:
one: 'aproximadamente 1 ano'
other: 'aproximadamente {{count}} anos'
over_x_years:
one: 'mais de 1 ano'
other: 'mais de {{count}} anos'
53
prompts:
year: "Ano"
month: "Mês"
day: "Dia"
hour: "Hora"
minute: "Minuto"
second: "Segundos"
# numeros
number:
format:
precision: 3
separator: ','
delimiter: '.'
currency:
format:
unit: 'R$'
precision: 2
format: '%u %n'
separator: ','
delimiter: '.'
percentage:
format:
delimiter: '.'
precision:
format:
delimiter: '.'
human:
format:
precision: 1
delimiter: '.'
storage_units:
format: "%n %u"
units:
byte:
one: "Byte"
other: "Bytes"
kb: "KB"
mb: "MB"
54
gb: "GB"
tb: "TB"
# Used in array.to_sentence.
support:
array:
words_connector: ", "
two_words_connector: " e "
last_word_connector: " e "
# Active Record
activerecord:
errors:
template:
header:
one: "Não foi possível gravar {{model}}: 1 erro"
other: "Não foi possível gravar {{model}}: {{count}} erros."
body: "Por favor, verifique o(s) seguinte(s) campo(s):"
messages:
inclusion: "não está incluído na lista"
exclusion: "não está disponível"
invalid: "não é válido"
confirmation: "não está de acordo com a confirmação"
accepted: "deve ser aceito"
empty: "não pode ficar vazio"
blank: "não pode ficar em branco"
too_long: "é muito longo (máximo: {{count}} caracteres)"
too_short: "é muito curto (mínimo: {{count}} caracteres)"
wrong_length: "não possui o tamanho esperado ({{count}} caracteres)"
taken: "já está em uso"
not_a_number: "não é um número"
greater_than: "deve ser maior do que {{count}}"
greater_than_or_equal_to: "deve ser maior ou igual a {{count}}"
equal_to: "deve ser igual a {{count}}"
less_than: "deve ser menor do que {{count}}"
less_than_or_equal_to: "deve ser menor ou igual a {{count}}"
odd: "deve ser ímpar"
even: "deve ser par"
55
Nesse ponto o projeto já está criado e configurado, é necessário criar então os
cadastros de cliente, vendedor e produto
A partir daqui o procedimento se repetirá para cada cadastro do sistema
Cadastro de clientes
Criar o model cliente
No shell:
script/generate model cliente nome:string datanasc:date
fone:string endereco:string cep:string bairro:string cidade:string estado:string
numcli:integer rg:string
Criar a tabela clientes no banco
No shell:
rake db:migrate
Criar o controller
No shell:
script/generate controller clientes #aqui é necessário acrescentar a letra
„s‟ no final # (por padrão do rails)
No controller criado, é necessário adicionar o seguinte código (no aptana) :
active_scaffold :clientes do | config |
end
Adicionar uma rota no arquivo /config/routes.rb (no aptana):
map.resources :clientes, :active_scaffold => true
56
Definir os campos do grid (no aptana)
Editar o controller, acrescentando na classe:
active_scaffold :contato do | config | #isso já foi inserido no passo 8.4
config.columns = [:numcli , :nome, :rg, :datanasc, :fone, :endereco, :cep,
:bairro , :cidade, :estado ]
config.list.per_page = 10 #adiciona paginação a cada 10 registros
end #isso já foi inserido no passo 8.4
Definir a descrição na edição do registro (no aptana)
Editar o model, acrescentando na classe:
def to_s
nome
end
Aqui o Cadastro está criado com as funções de inclusão, consulta (por qualquer
campo do cadastro), alteração e exclusão.
Figura 6 - tela inicial do cadastro de clientes
57
Figura 7 - Tela de inclusão de cadastro
Figura 8 - Consulta de Clientes
Cadastro de vendedores
Criar o model vendedor
58
No shell:
script/generate model vendedor nome:string datanasc:date
fone:string endereco:string cep:string bairro:string cidade:string estado:string
numvnd:integer comissao:float
Criar a tabela vendedores no banco
No shell:
rake db:migrate
Criar o controller
No shell:
script/generate controller vendedors
No controller criado , é necessário adicionar o seguinte código (no
aptana) :
active_scaffold :vendedors do | config |
end
Adicionar uma rota no arquivo /config/routes.rb (no aptana):
map.resources :vendedors, :active_scaffold => true
Definir os campos do grid (no aptana)
Editar o controller, acrescentando na classe:
59
active_scaffold :vendedors do | config | #isso já foi inserido no passo 9.4
config.columns = [:numvnd , :nome, :datanasc, :fone, :endereco, :cep,
:bairro , :cidade, :estado , :comissao]
config.list.per_page = 10 #adiciona paginação a cada 10 registros
end #isso já foi inserido no passo 9.4
Definir a descrição na edição do registro (no aptana)
Editar o model, acrescentando na classe:
def to_s
nome
end
Cadastro de produtos
Criar o model produto
No shell:
script/generate model produto descricao:string preco:float
codigo:string icms:float ipi:float
Criar a tabela produtos no banco
No shell:
rake db:migrate
Criar o controller
No shell:
script/generate controller produtos
60
No controller criado , é necessário adicionar o seguinte código (no
aptana) :
active_scaffold :produtos do | config |
end
Adicionar uma rota no arquivo /config/routes.rb (no aptana):
map.resources :produtos, :active_scaffold => true
Definir os campos do grid (no aptana)
Editar o controller, acrescentando na classe:
active_scaffold :produtos do | config | #isso já foi inserido no passo 9.4
config.columns = [:codigo , :descricao, :preco, :icms, :ipi]
config.list.per_page = 10 #adiciona paginação a cada 10 registros
end #isso já foi inserido no passo 9.4
Definir a descrição na edição do registro (no aptana)
Editar o model, acrescentando na classe:
def to_s
descricao
end
61
Criar um menu de navegação:
No arquivo /app/views/layoutsaplication.html.erb adicionar os links para cada
cadastro. O arquivo ficará assim:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<%= stylesheet_link_tag 'default.css' %>
<title>Agenda</title>
<%= javascript_include_tag :defaults %>
<%= active_scaffold_includes %>
</head>
<body>
<%= link_to 'Clientes' , clientes_url %>
<%= link_to 'Vendedores' , vendedors_url %>
<%= link_to 'Produtos' , produtos_url %>
<%= yield %>
</body>
</html>
Preparar a Index
Deletar o arquivo index.html da pasta /public/
No arquivo /config/routes.rb:
Procure por:
# map.root :controller => “welcome”
Descomente essa linha e modifique para:
62
map.root :controller => "clientes"
Iniciar a aplicação(este procedimento pode ser feito a qualquer momento
para testar a aplicação, é necessário apenas alterar a url colocando o nome de
algum controller da aplicação. Por exemplo: http://localhost/3000/clientes ):
No Shell:
script/server start
No Browser:
acesse a url: http://localhost/3000/
Em Delphi:
Criar o banco de dados, as tabelas, os generators e os triggers que alimentam
os id‟s de cada tabela
/* tabela de cliente */
create table clientes(
id integer primary key,
nome varchar(255),
datanasc date,
fone varchar(255),
endereco varchar(255),
cep varchar(25),
bairro varchar(30),
63
cidade varchar(30),
estado varchar(2),
numcli integer,
rg varchar(25)
);
CREATE GENERATOR GN_CLIENTES;
SET TERM ^;
CREATE TRIGGER INSCLI FOR CLIENTES
ACTIVE BEFORE INSERT
AS
BEGIN
IF ((NEW.ID IS NULL) OR (NEW.ID = 0)) THEN
NEW.ID = GEN_ID(GN_CLIENTES,1);
END
^
SET TERM ; ^
/* TABELA DE VENDEDORES */
create table vendedores(
id integer primary key,
nome varchar(255),
datanasc date,
fone varchar(255),
endereco varchar(255),
cep varchar(25),
bairro varchar(30),
cidade varchar(30),
estado varchar(2),
numvnd integer,
comissao double precision
);
CREATE GENERATOR GN_VENDEDORES;
64
SET TERM ^;
CREATE TRIGGER INSVND FOR VENDEDORES
ACTIVE BEFORE INSERT
AS
BEGIN
IF ((NEW.ID IS NULL) OR (NEW.ID = 0)) THEN
NEW.ID = GEN_ID(GN_VENDEDORES,1);
END
^
SET TERM ; ^
/* TABELA DE PRODUTOS */
create table produtos(
id integer primary key,
descricao varchar(255),
preco double precision,
codigo varchar(40),
icms double precision,
ipi double precision
);
CREATE GENERATOR GN_PRODUTOS;
SET TERM ^;
CREATE TRIGGER INSPROD FOR PRODUTOS
ACTIVE BEFORE INSERT
AS
BEGIN
IF ((NEW.ID IS NULL) OR (NEW.ID = 0)) THEN
NEW.ID = GEN_ID(GN_PRODUTOS,1);
END
^
SET TERM ; ^
Criar Projeto no Delphi
65
Criar um MDIForm e o menu do sistema
Criar um DataModule para conexão no banco
Aqui é necessário colocar um componente de conexão ao banco e configurá-lo
para acessar o banco com dados como o caminho do banco, usuário, senha e o driver de
conexão ao banco.
No create do DataModule adicionar o código para abrir a conexão com o banco
de dados no inicio da execução do programa:
dbxDB.Open;
Criar os cadastros (Visando a máxima produtividade, e considerando que a
análise não considera questões de performance, foi utilizado DBNavigator
conectado a um DataSet sem Where)
Cadastro de Clientes
Inserir uma nova Form e defini-la como MDIChild
Remover o código do dpr (para não criar o form na inicialização do
programa):
Application.CreateForm(TfrmClientes, frmClientes);
Incluir no evento onClose do form o código (para fechar o MDIChild):
Action := caFree;
66
Incluir o DataModule na sessão Uses do form (neste caso a unit dm) :
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, dm;
Incluir os componentes de comunicação com o banco:
Incluir um dataset, um provider,um ClientDataSet e um DataSource e
fazer as ligações
No comandText do DataSet incluir o select :
SELECT * FROM CLIENTES
Incluir os campos na tela, incluir um DbNavigator. Para facilitar a
consulta foi incluído um grid e um edit na mesma tela. No OnChange do
edit a consulta foi implementada apenas no campo „nome‟.
Códigos utilizados:
No FormCreate:
cdsClientes.Open; // abre o ClientDataSet
67
No AfterPost do ClientDataSet e no AfterDelete do mesmo ClientDataSet:
cdsClientes.ApplyUpdates(0); //aplica alterações no banco
cdsClientes.Refresh; // atualiza o Client (porque o id é criado pelo trigger no
banco)
No onChange do edit, para filtrar o grid
cdsClientes.Filter := ' nome like ' + QuotedStr('%' + edNome.Text + '%');
Figura 9- Cadastro de Clientes em Delphi.
A consulta é feita (apenas pelo campo „Nome‟) digitando no Edit acima do Grid.
Cadastro de Vendedores
Inserir uma nova Form e defini-la como MDIChild
68
Remover o código do dpr (para não criar o form na inicialização do
programa):
Application.CreateForm(TfrmVendedores, frmVendedores);
Incluir no evento onClose do form o código (para fechar o MDIChild):
Action := caFree;
Incluir o DataModule na sessão Uses do form (neste caso a unit dm) :
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, dm;
Incluir os componentes de comunicação com o banco:
Incluir um dataset, um provider,um ClientDataSet e um DataSource e
fazer as ligações
No comandText do DataSet incluir o select :
SELECT * FROM Vendedores
Incluir os campos na tela, incluir um DbNavigator. Para facilitar a
consulta foi incluído um grid e um edit na mesma tela. No OnChange do
edit a consulta foi implementada apenas no campo „nome‟.
69
Códigos utilizados:
No FormCreate:
cdsClientes.Open; // abre o ClientDataSet
No AfterPost do ClientDataSet e no AfterDelete do mesmo ClientDataSet:
cdsClientes.ApplyUpdates(0); //aplica alterações no banco
cdsClientes.Refresh; // atualiza o Client (porque o id é criado pelo trigger no
banco)
No onChange do edit, para filtrar o grid
cdsVendedores.Filter := ' nome like ' + QuotedStr('%' + edNome.Text + '%');
Figura 10 - Cadastro de Vendedores
70
Cadastro de Produtos
Inserir uma nova Form e defini-la como MDIChild
Remover o código do dpr (para não criar o form na inicialização do
programa):
Application.CreateForm(TfrmProdutos, frmProdutos);
Incluir no evento onClose do form o código (para fechar o MDIChild):
Action := caFree;
Incluir o DataModule na sessão Uses do form (neste caso a unit dm) :
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, dm;
Incluir os componentes de comunicação com o banco:
Incluir um dataset, um provider,um ClientDataSet e um DataSource e
fazer as ligações
No comandText do DataSet incluir o select :
SELECT * FROM Produtos
71
Incluir os campos na tela, incluir um DbNavigator. Para facilitar a
consulta foi incluído um grid e um edit na mesma tela. No OnChange do
edit a consulta foi implementada apenas no campo „descricao‟.
Códigos utilizados:
No FormCreate:
cdsClientes.Open; // abre o ClientDataSet
No AfterPost do ClientDataSet e no AfterDelete do mesmo ClientDataSet:
cdsClientes.ApplyUpdates(0); //aplica alterações no banco
cdsClientes.Refresh; // atualiza o Client (porque o id é criado pelo
trigger no banco)
No onChange do edit, para filtrar o grid
cdsProdutos.Filter := ' descricao like ' + QuotedStr('%' + edDesc.Text + '%');
Criar chamadas no menu para os cadastros
Incluir no uses do MDIForm as units „clientes, vendedores, produtos‟:
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, Menus ,clientes, vendedores, produtos;
72
Incluir no click de cada botão do menu criado o código para criar e abrir
sua respectiva tela:
TfrmClientes.Create(nil).Show; // no click do item de menu clientes
TfrmVendedores.Create(nil).Show; //no click do item de menu
vendedores
TfrmProdutos.Create(nil).Show;//no click do item de menu produtos
Figura 11 - Cadastro de Produtos
73
4.2 Análise comparativa de criação de telas de cadastro Delphi X
RubyOnRails
Requisitos Delphi Ruby on Rails
Instalação Um instalador executa a instalação.
A instalação de alguns componentes
costuma ser simples (quando
necessário).
Comandos shell são
necessários. Alguns
problemas de
incompatibilidade de
versões podem ocorrer e
pode ser necessário recorrer
a alguns fóruns de ajuda
para sanar os problemas.
Configurações
gerais de um
projeto
Criar menus em um MDIForm, incluir
um pequeno código no OnClose de
todas as Child‟s (action:= caFree;)
para poder fechar o form.
É necessário configurar
arquivos e instalar e
configurar plugins para
cada aplicação.
Criação de
cadastros
É necessário montar a tela visualmente
e implementar um pouco de código. É
necessário criar o banco de dados e
gerenciar a comunicação com ele
através dos componentes.
O desenvolvimento
acontece pela IDE e por
comandos shell, o que pode
ser um pouco confuso
inicialmente. Porém o
74
desenvolvimento de telas
muitas vezes se dá sem
precisar montar a tela
visualmente nem codificá-
la. A conexão com o banco
é feita automaticamente,
pelo plugin ActiveScaffold.
Utilizando esse plugin é
possível se construir um
cadastro em cerca de 3
minutos com todas as ações
de um CRUD sem a
necessidade de codificar
essas ações.
75
5 IMPLEMENTAÇÃO DE VALIDAÇÕES
A implementação das validações é feita no Model do modelo MVC. O rails
possui alguns métodos de validações já implementadas (para as mais usadas), entre elas:
validates_presence_of(:nome , :message => "deve ser preenchido") #obriga o
preenchimento do campo
validates_uniqueness_of(:nome, :message => "já cadastrado") #bloqueia
duplicação de registros
validates_numericality_of(:idade, :greater_than => 0, :less_than => 100 ,
:message => "deve ser um numero entre 0 e 100") #validações numéricas
validates_associated :cliente # valida integridade referencial
Para usar esses métodos de validações, inclui-se no Model desejado o código.
Continuando com os cadastros criados previamente, a seguir estão os passos
para criar algumas validações em Rails:
Validações:
Obrigar o campo nome no cadastro de clientes
No Model “cliente.rb” (da pasta /app/models), adicione dentro da classe a linha:
validates_presence_of(:nome , :message => "deve ser preenchido")
76
Impedir duplicação no campo RG no cadastro de clientes
No Model “cliente.rb” (da pasta /app/models), adicione dentro da classe a linha:
validates_uniqueness_of(:rg, :message => "já cadastrado")
Validar o campo RG para receber apenas números
No Model “cliente.rb” (da pasta /app/models), adicione dentro da classe a linha:
validates_numericality_of(:rg , :message => "deve ser apenas números")
Figura 12 - exemplo de mensagem de validação de campo
77
5.1 Análise comparativa com Delphi:
Para obrigar o preenchimento de um campo e mostrar uma mensagem
explicativa ao usuário, em Delphi, seria necessário algo como:
Verificar a property isNull do field desejado do ClientDataSet antes de dar o
post no ClientDataSet. Algo como:
if cdsClientesNome.isNull then
begin
ShowMessage(„O campo Nome é obrigatório‟);
exit;
end;
Nesse caso é tão simples quanto no rails. Porém para verificar se o registro é
único, como no exemplo de impedir cadastrar um cliente com um RG que já exista no
sistema:
No Rails a chamada validates_uniqueness_of(:rg, :message => "já
cadastrado") dentro do model Cliente.rb resolveria. Mas no Delphi, por exemplo, como
é inviável abrir todo a tabela no ClientDataSet (por questões de performance, quando se
tem um cadastro com muitos registros), seria necessário criar uma função que
verificasse com um select no banco de dados se existe um registro que já possui aquele
RG.
Além da funções nativas de validações, é possível criar funções para validações
específicas, por exemplo:
78
validate :primeira_letra_maiuscula
private
def primeira_letra_maiuscula
errors.add("nome","primeira letra deve ser maiúscula") unless nome =~ /[A-Z].*/
end
}
Em ambiente web é muito comum o desenvolvedor precisar implementar
mecanismos que cuidem para não perder os dados durante a validação do formulário
(implementando a validação e Ajax, mantendo o conteúdo em session, etc). Porém no
rails isso é feito sem a intervenção do programador. Tanto usando validações nativas,
quanto implementando as validações, o gerenciamento para manter os dados que o
usuário digitou no formulário é feito de forma transparente para o desenvolvedor. E
todas as validações foram feitas sem a necessidade de escrever nenhuma linha de
JavaScript.
79
6 SEGURANÇA EM RAILS
6.1 As principais formas de invasão na Web
Na web existem diversas formas de invasão, mas destas 3 pontos são
fundamentais de vulnerabilidade dos sistemas Web:
HTML Injection
SQL Injection
Cross site scripting
Html Injection consiste em cadastrar tags HTML ou Javascript em formulários ,
por exemplo, no cadastro de clientes o usuário pode informar no campo nome :
"<script>alert("site inseguro")</script>". Em um sistema sem proteção contra HTML
Injection, ao visualizar uma página que imprimiria o nome do usuário, seria executado o
comando Java script (que pode ter diversos comportamentos indesejáveis)
SQL Injection é a habilidade de inserir SQL de modo a modificar os comandos
de uma determinada view do sistema , por exemplo , em uma tela que executa a
seguinte query:
'select senha , nome from usuarios where usuario = ' + edit1.value + ' '
80
Supondo que o usuário digite no edit1 o seguinte : a' or ' 1 = 1
Com isso ele consegue concatenar uma expressão no where da query (no caso a
expressão „ or 1=1‟ ) e ele pode conseguir ver todos os usuários cadastrados no banco
de dados.
Cross site scripting é uma formas de invasão muito poderosa, que consiste em
criar uma página pirata que consegue utilizar das sessões abertas para realizar uma
invasão , por exemplo :
Estatísticas dizem que 60 % dos usuários atuais da web trabalham logados no
gmail e conseqüentemente no googledocs, baseado nisso um hacker cria uma página
pirata com a seguinte action disparada por Java script :
'http://mail.google.com/mail/?method=_delete&cod_msg=1' , ou seja deleta o primeiro
email do usuário.
É muito comum desenvolvedores web não se preocuparem com esse tipo de
situação. Talvez por costume, por não ser um padrão entre os desenvolvedores esse tipo
de precaução ou talvez pelo trabalho de implementar proteções desse tipo.
6.2 As proteções nativas do rails
O rails tem proteção nativa para as principais formas de ataque:
Para proteger a aplicação de HTML injection basta introduzir a letra h , antes de
imprimir um valor numa view, por exemplo : <%=h c.nome %>
81
Utilizando o ActiveScaffold para a criação de cadastros essa proteção já está
implementada por padrão.
Para proteger contra SQL injection, o rails tem o método find() com conditions
que previne automaticamente grande parte dos métodos de SQL Injection. não utilizar o
findbysql.
O Ruby on Rails tem um filtro nativo de proteção contra SQL injection, o qual
irá escapar ‟ , " , o caractere NULL e quebras de linhas. Utilizando o método find(id) ou
findby_something(something) automaticamente aplica esta medida preventiva.
Assim, evita-se usar o método findby_sql() que não possui essa proteção nativa.
Utilizando esse método, é necessário implementar a proteção manualmente.
A proteção contra ataque de cross-site, é ativa no rails por padrão. Não é
necessário fazer nada.
6.3 Análise comparativa com PHP
Em comparação com outras linguagens web, por exemplo o php, para evitar a
SQL Injection seria necessário criar uma função para o tratamento das querys. O php
possui a função mysql_real_escape_string(), que escapa os caracteres especiais como
aspas simples e duplas antes de enviar para o banco de dados. Porém esta função não
funciona em todas as versões do PHP, então é necessário verificar se ela existe, e caso
não exista utiliza-se outra função, a mysql_escape_string().
82
Também é necessário se preocupar que se a diretiva get_magic_quotes_gpc()
estiver ON ele irá acrescentar barras invertidas automaticamente antes de aspas simples
e duplas, o problema é que ele irá enviar para o banco de dados com as barras
invertidas, estragando o texto. Para contornar isso é necessário usar a função
stripslashes() para remover essas barras invertidas.
O código da função ficaria parecido com:
<?php
function anti_sql_injection($string)
{
$string = get_magic_quotes_gpc() ? stripslashes($string) : $string;
$string = function_exists("mysql_real_escape_string") ?
mysql_real_escape_string($string) : mysql_escape_string($string);
return $string;
}
?>
Enquanto que no rails já existe o método find(id) ou
findby_something(something) que implementa essa segurança automaticamente.
Também em php, contra HTML injection, o desenvolvedor teria que
implementar manualmente, tomando o devido cuidado para não causar outros
problemas no sistema. Enquanto que em rails é necessário colocar o caractere „h‟ antes
do campo. Por exemplo, <%=h c.nome %> . E utilizando alguns frameworks como o
ActiveScaffold na criação dos cadastros essa proteção já funciona sem a intervenção do
programador.
83
CONCLUSÃO
Assim como a maioria das ferramentas para desenvolvimento web, o rails tem
complexidades para instalação (configuração de alguns arquivos, uma série de
comandos shell, etc) e como a instalação é feita por partes (não existe um instalador
único, são necessários comandos para o ruby, o rails, as gems, os plugins, etc) podem
ocorrer alguns problemas durante a instalação. Ferramentas de desenvolvimento
desktop não costumam ter esse tipo de complexidade (como o delphi).
No inicio do projeto são necessários alguns ajustes de idioma e template de html
e css, mas que pode ser contornado com a criação de um template padrão de projeto que
seria herdado para a criação das aplicações, ou apenas com procedimentos bem
definidos para evitar que alguma etapa seja esquecida e gere problemas futuros.
O desenvolvimento do projeto é prático e facilitado por alguns frameworks
como o ActiveScaffold, que gera todo um cadastro sem a necessidade do programador
codificar o cadastro, desenhar as telas ou até mesmo criar o banco de dados (apenas
quando desejável pode se customizar as telas de acordo com a necessidade). Algumas
customizações como a validações de campos já são bem pré-implementadas com a
criação de métodos que facilitam a implementação através de chamados simples a esses
métodos.
O rails já vem preparado contra os problemas mais comuns de segurança na web
(que costuma ser ignorada por uma parte dos programadores web e trabalhosa para a
outra parte que se preocupa com isso). Ele já possui alguns mecanismos de segurança
embutidos e outros que são facilmente implementados. Seus plugins também
implementam os métodos de segurança oferecidos pelo rails.
84
BIBLIOGRAFIA
EDUARDO: Por que Ruby on Rails? Disponível em:
<http://imasters.com.br/artigo/4746/programacao/porque_ruby_on_rails >. Acesso em:
14 Jul. 2010
FOWLER, Chad. Rails Recipes. Texaz, Pragmatic Bookshelf, 2007
Hansson: Ruby on Rails 2.1.x Tutorial. Disponível em:
<http://www.tutorialspoint.com/ruby-on-rails-2.1/index.htm >. Acesso em: 14 Jul. 2010
STEWART: An Interview with the creator of Ruby. Disponível em:
<http://linuxdevcenter.com/pub/a/linux/2001/11/29/ruby.html >. Acesso em: 14 Jul.
2010
THOMAS, Dave; HANSSON, David Heinemeier. Agile Web Development with
Rails. 3ª ed. Pragmatic Bookshelf, 2009
URUBATAN, Rodrigo. Ruby on Rails Desenvolvimento fácil e rápido de aplicações
web. Novatec, 2009
YEHUDA: Metaprogramming in Ruby. Disponível em:
<http://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about-the-self/ >.
Acesso em: 14 Jul. 2010
FATEC – SP
Faculdade de Tecnologia de São Paulo
Desenvolvimento ágil
com Ruby on Rails
São Paulo, SP
2010
Recommended