SlideShare uma empresa Scribd logo
1 de 64
Baixar para ler offline
Ruby on Rails




Regis Pires Magalhães
       regispiresmag@gmail.com
http://regispiresmag.googlepages.com
   Última atualização em 24/01/2007
Instalação do Ruby

1 – No Linux - http://rubyforge.org/frs/download.php/7858/ruby-
1.8.4.tar.gz
       tar xvzf ruby-<versão>.tgz
       ./configure
       make
       make install
2 – No Windows - One-Click Installer – já vem com RubyGems:
     http://rubyforge.org/frs/download.php/11488/ruby184-20.exe
Instalação do RubyGems

• Desnecessário no Windows, pois já vem no One-Click Installer
• RubyGems - gerenciador de pacotes do Ruby

1 – Descompactar:
  http://rubyforge.org/frs/download.php/11290/rubygems-0.9.0.zip

2 – Executar:
    ruby setup.rb
Instalação do Rails


• Via Internet:
   gem install rails --include-dependencies
• Local:
   – Ir para diretório onde estão os arquivos gem e executar:
     gem install activesupport actionpack actionmailer
     activerecord actionwebservice rails –-local
   – Arquivos necessários:
       •   rails-1.1.6.gem
       •   actionmailer-1.2.5.gem
       •   actionpack-1.12.5.gem
       •   actionwebservice-1.1.6.gem
       •   activerecord-1.14.4.gem
       •   activesupport-1.3.1.gem
Instalação do PostgreSQL


• No Windows:
  – Descompactar:
     • postgresql-8.1.4-1.zip
  – Executar:
     • postgresql-8.1.msi
Instalação da biblioteca do PostgreSQL para o
                      Ruby


• Via internet:
    gem install postgres-pr
• Local:
    gem install postgres-pr –-local
Criação do Banco de Dados

create database <projeto>_<ambiente>

create database livraria_development

Ambientes:
• Development - desenvolvimento
• Test - testes
• Production - produção
Criação de tabelas
• usuarios                           • tipos
   –   id serial (PK)                   – id serial (PK)
   –   nome varchar(75)                 – descricao varchar(50)
   –   email varchar(75)
   –   senha varchar(10)
                                     • telefones
   –                                    – id serial (PK)
       admin int4
   –                                    – usuario_id int4
       img bytea
                                        – numero varchar(10)

• categorias                         • produtos
   – id serial (PK)                     –   id serial (PK)
   – descricao varchar(50)              –   descricao varchar(100)
                                        –   tipo_id int4
                                        –   categoria_id int4
Criação do Projeto

rails <projeto>

>rails livraria
create
create app/controllers
create app/helpers
create app/models
create app/views/layouts
create config/environments
create components
create db
create doc
create lib
create lib/tasks
create log
...
Configuração do acesso
                a banco de dados

• Abrir arquivo config/database.yml:
   development:
     adapter: postgresql
     database: livraria_development
     username: postgres
     password: 1234
     host: localhost
   ...
Testando o Servidor WEB

ruby script/server

ruby script/server –e [development|test|production]

• Development é o default.
Geração de um Scaffold
• Scaffold - tradução: andaime, palanque, armação , esqueleto
• Scaffold é um meio de criar código para um determinado modelo
  através de um determinado controlador.
• É um meio de começarmos rapidamente a ver os resultados no
  navegador Web e um método muito rápido de implementar o CRUD
  (Create, Retrieve, Update, Delete) na sua aplicação.

  ruby script/generate scaffold <Model> <Controller>

  ruby script/generate scaffold Usuario Admin::Usuario

• O controlador Admin::Usuario gerenciará as ações recebidas. O rails irá
  criar a seguinte estrutura de diretórios:
  <aplicação>/controllers/admin
Outras gerações comuns

• Modelo:
 ruby script/generate model <Model>


• Controlador:
 ruby script/generate controller <controller>
Diretórios da aplicação
• controllers
   – Classes de controle.
   – Uma classe controller trata uma requisição Web do usuário.
   – A URL da requisição Web é mapeada para uma classe de controle e
     para um método dentro da classe.
• views
   – Armazena as templates de visualização para preenchimento com
     dados da aplicação, conversão para HTML e retorno para o browser.
• models
   – Armazena as classes que modelam e encapsulam dos dados
     armazenados nos bancos de dados da aplicação.
• helpers
   – Armazena classes de auxílio usadas para ajudar as classes model,
     view e controller. Ajudam a manter os códigos de model, view e
     controller bastante enxutos.
Modelo
<aplicação>/app/models/usuario.rb:

   class Usuario < ActiveRecord::Base
   end

• A classe Usuario já é capaz de gerenciar os dados da tabela no
  banco de dados.
• Não há necessidade de explicitar o mapeamento das colunas do
  banco com atributos da classe.
• Rails não proíbe nada: se for necessário existe como mapear
  uma coluna para outro atributo de nome diferente.
• Nome de tabela diferente da convenção:

   class EncomendaCliente < ActiveRecord::Base
       set_table_name quot;encomendas_clientesquot;
   end
Modelo
• Toda entidade é criada no diretório padrão:
   /app/models/<controller>/<model>.rb
• Toda entidade herda diretamente da classe
  ActiveRecord::Base      .
• Não há necessidade de mapear manualmente cada coluna
  da tabela.
• Convenção: a classe tem o nome no singular (Usuario), a
  tabela tem o nome do plural (usuarios).
• Convenção: Toda tabela tem uma chave primária chamada
  id que é de tipo auto-incremento.
Active Record Interativo

ruby script/console
• Toda entidade criada pode ser manipulada
  pelo console.
• Facilita testes antes de criar as actions.
Acrescentando validação
class Usuario < ActiveRecord::Base
  validates_presence_of :nome
  validates_length_of :nome,
                      :maximum => 75,
                      :message => quot;Máximo de %d caracteres.quot;
end

Outros exemplos:
  validates_uniqueness_of :cpf
  validates_length_of :cpf, :is => 11
  validates_length_of :user_name, :within => 6..20,
                      :too_long => quot;deve ser menorquot;,
                      :too_short => quot;deve ser maiorquot;
  validates_length_of :first_name, :maximum=>30
Controller
• Todo Controller fica no diretório:
     /app/controllers/<nome>_controller.rb
• Todo Controller herda a classe ApplicationController
• Todo aplicativo Rails é criado com uma classe chamada
  ApplicationController que herda de
                               ,
  ActionController::Base e é base de todos os outros
                                 ,
  controllers
• Todo método de um controller é chamado de Action
• Uma classe Controller pode ter quantas Actions quanto
  necessárias.
       class Admin::UsuarioController < ApllicationController
         def index
              render :text => “Hello World!”
         end
       end
Acessando uma Action
• Roteamento Customizável (routes.rb)
  http://localhost:3000/:controller/:action/:id

• Exemplo:
  http://localhost:3000/blog/index
     • blog = app/controller/blog_controller.rb
     • index = método index em BlogController
View
index.rhtml:
<h3>Hello da View!</h3>

blog_controller.rb:
Mais convenções
• Ao final de toda Action, Rails chamará uma view
  com o mesmo nome da Action, no seguinte
  diretório:
  /app/views/<controller>/<action>.<ext>
• A extensão do arquivo pode ser:
  – .rhtml - Embedded Ruby (HTML+Ruby)
  – .rxml - XML Builder (Ruby puro)
  – .rjs - Javascript Generator (Ruby puro)
• Este fluxo pode ser interrompido com uma
  chamada explícita ao método render ou
  redirect_to.
Modificando a listagem

/app/views/admin/usuario/list.rhtml


• Podemos alterar o layout ou qualquer
  código como quisermos.
Layouts

• Layouts permitem o compartilhamento de conteúdo.
• Todo novo controller automaticamente ganha um
  layout no diretório:
  /app/views/layouts/<controller>.rhtml

• As views desse controller preenchem o espaço:
  <%= @content_for_layout %>
Layouts
# test_controller.rb
class TestController < ApplicationController
  layout quot;defaultquot;

  def index
  end

end

                 <!-- default.rhtml -->
                 <html>
                 <head>
                    <title>Teste</title>
                 </head>

                 <body>
                    <h1>Layout Padrao</h1>
                    <%= @content_for_layout %>
                 </body>

                 </html>
Scriptlets

<% @usuarios.each do |usuario| %>
Faz alguma coisa com usuario
<% end %>
...
<% if number == quot;7quot; %>
Está correto!
<% end %>
Flash
• flash[:notice] está disponível somente
  naquela requisição. Usado para comunicação
  entre ações: passagem de string contendo
  informação ou erro.
• Similar a variáveis de sessão, mas somente
  existe de uma página para outra. Uma vez
  que a requisição para a qual foram
  propagadas acaba, elas são
  automaticamente removidas do contexto de
  execução.
  def three
   flash[:notice] => quot;Helloquot;
   flash[:warning] => quot;Mewlquot;
   flash[:error] => quot;Erro!quot;
   render
 end
Logger
• Nível de log configurado em:
  config/environment.rb:
   config.log_level = :debug
• Mensagens escritas em um arquivo no
  diretório log. O arquivo de log usado depende
  do ambiente (environment) usado pela
  aplicação. Ex.: log/development.log
 logger.warn(quot;I don't think that's a good ideaquot; )
 logger.info(quot;Dave's trying to do something badquot; )
 logger.error(quot;Now he's gone and broken itquot; )
 logger.fatal(quot;I give upquot; )
Paginação
  • Para todas as ações do Controller:
class PersonController < ApplicationController
      model :person
      paginate :people, :order => 'last_name, first_name',
               :per_page => 20
      # ...
end
Paginação

 • Para uma única ação do Controller:
def list
   @person_pages, @people =
      paginate :people, :order => 'last_name, first_name'
end
Paginação

   • Condicional
@upcoming_event_pages, @upcoming_events = paginate
   :upcoming_event, :conditions => quot;event LIKE
      '%quot;params['upcoming_event']['search'].to_squot;%'quot;,
   :order_by => quot;date DESCquot;, :per_page => 10
Paginação

  • Genérica
def list
   @person_pages = Paginator.new self, Person.count, 10,
                   params[:page]
   @people = Person.find :all, :order => 'last_name, first_name',
                         :limit   =>   @person_pages.items_per_page,
                         :offset =>    @person_pages.current.offset
 end
Paginação
• paginate(collection_id, options={}) – Retorna um paginator e
  uma coleção de instâncias de modelo Active Record para a página
  atual.
• Opções:
   – :singular_name: the singular name to use, if it can‘t be inferred by singularizing the
     collection name
   – :class_name: the class name to use, if it can‘t be inferred by camelizing the singular
     name
   – :per_page: the maximum number of items to include in a single page. Defaults to 10
   – :conditions: optional conditions passed to Model.find(:all, *params) and Model.count
   – :order: optional order parameter passed to Model.find(:all, *params)
   – :order_by: (deprecated, used :order) optional order parameter passed to
     Model.find(:all, *params)
   – :joins: optional joins parameter passed to Model.find(:all, *params) and Model.count
   – :join: (deprecated, used :joins or :include) optional join parameter passed to
     Model.find(:all, *params) and Model.count
   – :include: optional eager loading parameter passed to Model.find(:all, *params) and
     Model.count
   – :select: :select parameter passed to Model.find(:all, *params)
   – :count: parameter passed as :select option to Model.count(*params)
Paginação
   • Em um array / collection:
 def paginate_collection(collection, options = {})
    default_options = {:per_page => 10, :page => 1}
    options = default_options.merge options

    pages = Paginator.new self, collection.size, options[:per_page],
            options[:page]
    first = pages.current.offset
    last = [first + options[:per_page], collection.size].min
    slice = collection[first...last]
    return [pages, slice]
  end


@pages, @users = paginate_collection User.find_custom_query,
                 :page => @params[:page]
Convenção de Nomes
Fluxo do MVC
Parâmetros de Forms
Associações
• Todo usuario pode ter vários telefones.
• Telefone pertence a Usuario através da coluna usuario_id.
• Convenção de Chave Estrangeira: <classe>_id
class Usuario < ActiveRecord::Base
  has_many :telefones # um usuário tem muitos telefones
  validates_presence_of :nome
  validates_length_of :nome,
                      :maximum => 75,
                      :message => quot;Máximo de %d caracteres.quot;
end

class Telefone < ActiveRecord::Base
    belongs_to :usuario # um telefone pertence a um usuário
end
Associações

• Um para Um
Associações

• Um para Muitos
Associações

• Muitos para Muitos
Mapeamento de Tipos
Rake
• Programa em Ruby para realizar um
  conjunto de tarefas (tasks).
• Cada tarefa tem um nome, uma lista de
  tarefas das quais ela depende e uma lista
  de ações a realizar.
• Para ver as tarefas existentes em um
  arquivo rake (Rakefile):
  rake --tasks
Testes Unitários
• Toda nova entidade ganha um arquivo para teste unitário em:
   /app/test/unit/<entidade>_test.rb
• Devemos seguir os preceitos de Test-Driven Development:
   “Se não vale a pena testar, para que estamos codificando?”
• Os testes acontecem em banco de dados separado do
  desenvolvimento
   <projeto>_test
• Cada teste roda de maneira isolada: os dados modificados em um teste
  não afetam outro teste
• Cada teste unitário tem um arquivo de “fixture”, carga de dados para
  testes:
   /app/test/fixture/<tabela>.yml
• Executando todos os testes unitários
   rake test:units
• Executando apenas um teste unitário:
   ruby test/unit/<entidade>_test.rb
Testes Unitários
require File.dirname(__FILE__) + '/../test_helper'
class PostTest < Test::Unit::TestCase
  fixtures :posts
  # Replace this with your real tests.
  def test_add_comment
      # adiciona um post
      @post = Post.create(:title => 'New Post',
        :body => 'New Post',
        :author => 'Anonymous')
      # adiciona um comment
      @comment = @post.comments.create(:body => 'New Comment',
        :author => 'Anonymous')
      assert_not_equal nil, @comment
      # recarrega a entidade
      @post.reload
      # checa se existe apenas um post
      assert_equal 3, Post.count # já existem 2 posts na fixture
      # checa se esse post tem apenas um comment
      assert_equal 1, @post.comments.count
  end
end
Fixture YAML

• “YAML Ain’t a Markup Language”
• Maneira de serializar objetos Ruby em
  forma de texto
• Formato humanamente legível
• Mais leve e simples que XML
Fixture YAML
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

ronaldo:
  id: 1
  name: Ronaldo
  login: ronaldo
  admin: true
  email: ronaldo@reflectivesurface.com
  data: 2004-07-01 00:00:00
  hashed_password: <%= Digest::SHA1.hexdigest('abracadabra') %>
marcus:
  id: 2
  name: Marcus
  login: marcus
  admin: false
  email: marcus@reflectivesurface.com
  data: <%= 1.day.from_now.strftime(quot;%Y-%m-%dquot;) %>
  hashed_password: <%= Digest::SHA1.hexdigest('teste') %>
Fixture YAML
Fixture YAML
Testes Unitários
Testes Unitários
Testes Unitários
Testes Funcionais

• Todo novo controller ganha uma classe de teste em:
  /app/test/functional/<classe>_controller_test.rb
• Devemos testar cada action do controller
• Métodos como get e post simulam navegação com um
  browser
• Executando todos os testes funcionais:
   rake test:functionals
• Executando apenas um testes funcional:
   ruby test/functional/<classe>_controller_test.rb
Testes Funcionais
require File.dirname(__FILE__) + '/../test_helper'
require 'blog_controller'


# Re-raise errors caught by the controller.
class BlogController; def rescue_action(e) raise e end; end


class BlogControllerTest < Test::Unit::TestCase
 fixtures :posts


 def setup
      @controller = BlogController.new
      @request    = ActionController::TestRequest.new
      @response   = ActionController::TestResponse.new
 end


 def test_create
      num_posts = Post.count # checa total de posts atual
      # simula submit do formulário de criar novo post
      post :create, :post => {:title => 'New Title', :body => 'New Post', :author => 'Anonymous'}
      # checa se depois da action fomos redirecionados
      assert_response :redirect
      # checa se realmente foi acrescentado um novo post
      assert_equal num_posts + 1, Post.count
 end
end
Testes Funcionais
require File.dirname(__FILE__) + '/../test_helper'
require 'users_controller'


# Re-raise errors caught by the controller.
class UsersController; def rescue_action(e) raise e end; end


class UsersControllerTest < Test::Unit::TestCase
 fixtures :users


 def setup
      @controller = UsersController.new
      @request     = ActionController::TestRequest.new
      @response    = ActionController::TestResponse.new
 end


 def test_index
      get :index
      assert_redirected_to :controller => quot;loginquot;, :action => quot;loginquot;
 end


 def test_index_with_login
      @request.session[:user] = users(:ronaldo).id
      get :index
      assert_response :success
      assert_tag :tag => quot;tablequot;, :children => { :count => User.count + 1,
       :only => { :tag => quot;trquot; } }
      assert_tag :tag => quot;tdquot;, :content => users(:ronaldo).name
 end
end
Testes Funcionais
Testes Funcionais
Testes de Integração

• Para gerar o teste:
  script/generate integration_test login
• Para executar o teste:
  rake test:integration
Testes de Integração
require quot;#{File.dirname(__FILE__)}/../test_helperquot;

class LoginTest < ActionController::IntegrationTest
  fixtures :users

  def test_login

    user = users(:ronaldo)

    get quot;/homequot;
    assert_redirected_to quot;/login/loginquot;

    follow_redirect!

    assert_response :success

    post quot;/login/loginquot;
    assert_response :success
    assert_equal quot;Invalid login and/or password.quot;, flash[:notice]

    post quot;/login/loginquot;, :login => user.login, :password => user.password
    assert_redirected_to quot;/homequot;

    follow_redirect!

    assert_tag :tag => quot;divquot;, :attributes => { :id => quot;edit_formquot; }

  end
end
Teste de Performance
Mais Testes
• Testes Unitários devem testar todos os aspectos da
  entidade como associações, validações, callbacks,
  etc
• Testes Funcionais devem testar todas as actions de
  um mesmo controller, todos os fluxos,
  redirecionamentos, filtros, etc
• Testes Integrados servem para avaliar a navegação
  e fluxos entre actions de diferentes controllers.
  Funcionam de maneira semelhante a um teste
  funcional
Helpers

# Global helper para views.
module ApplicationHelper
  # Formata um float com duas casa decimais
  def fmt_decimal(valor, decimais)
        sprintf(quot;%0.#{decimais}fquot; valor)
                                ,
  end
end
O que NÃO fizemos
• Não precisamos recompilar e reinstalar o aplicativo a cada
  mudança.
• Não precisamos reiniciar o servidor a cada mudança.
• Não precisamos mapear cada uma das colunas das tabelas para
  as entidades.
• Não precisamos configurar dezenas de arquivos XML.
  Basicamente colocamos a senha do banco de dados, apenas.
• Não precisamos usar Javascript para fazer Ajax: a maior parte
  pode ser feita com Ruby puro.
• Não sentimos falta de taglibs: expressões Ruby, partials foram
  simples o suficiente.
• Não precisamos codificar código-cola, o framework possui
  “padrões espertos” afinal, todo aplicativo Web tem a mesma
  infraestrutura.
Referências
• Agile Web Development with Rails. 2ª Edição.
   – Thomas e David Heinemeier Hansson.
• Entendendo Rails
   – Fábio Akita (http://www.esnips.com/web/BalanceOnRails)
• Creating a weblog in 15 minutes
   – http://media.rubyonrails.org/video/rails_take2_with_sound.mov
• Tutorial de Rails do TaQ
   – http://www.eustaquiorangel.com/downloads/tutorialrails.pdf
• Tutorial de Ruby on Rails do Ronaldo Ferraz
   – http://kb.reflectivesurface.com/br/tutoriais/rubyOnRails
• Rolling with Ruby on Rails by Curt Hibbs
   – http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html
• Tutorial de Ruby do TaQ
   – http://www.eustaquiorangel.com/downloads/tutorialruby.pdf

Mais conteúdo relacionado

Mais procurados

Tutorial - Visão sobre Automação de Testes com CasperJS
Tutorial - Visão sobre Automação de Testes com CasperJSTutorial - Visão sobre Automação de Testes com CasperJS
Tutorial - Visão sobre Automação de Testes com CasperJSFrederico Allan
 
Tutorial visão automação de testes e casper js
Tutorial visão automação de testes e casper jsTutorial visão automação de testes e casper js
Tutorial visão automação de testes e casper js4ALL Tests
 
Oficina groovy grails - infoway
Oficina  groovy grails - infowayOficina  groovy grails - infoway
Oficina groovy grails - infowayLucas Aquiles
 
Behavior Driven Development com Ruby on Rails
Behavior Driven Development com Ruby on RailsBehavior Driven Development com Ruby on Rails
Behavior Driven Development com Ruby on RailsMarco Antonio Filho
 
XML Free Programming - Brazil
XML Free Programming - BrazilXML Free Programming - Brazil
XML Free Programming - BrazilStephen Chin
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpecNando Vieira
 
Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN StackBruno Catão
 
Javascript no SAPO e libsapojs
Javascript no SAPO e libsapojsJavascript no SAPO e libsapojs
Javascript no SAPO e libsapojscodebits
 
Introdução ao Desenvolvimento de aplicações WEB com JSP
Introdução ao Desenvolvimento de aplicações WEB com JSPIntrodução ao Desenvolvimento de aplicações WEB com JSP
Introdução ao Desenvolvimento de aplicações WEB com JSPManoel Afonso
 
Introdução a Grails: Um framework veloz e poderoso
Introdução a Grails: Um framework veloz e poderosoIntrodução a Grails: Um framework veloz e poderoso
Introdução a Grails: Um framework veloz e poderosoBruno Lopes
 

Mais procurados (18)

Tutorial - Visão sobre Automação de Testes com CasperJS
Tutorial - Visão sobre Automação de Testes com CasperJSTutorial - Visão sobre Automação de Testes com CasperJS
Tutorial - Visão sobre Automação de Testes com CasperJS
 
Tutorial visão automação de testes e casper js
Tutorial visão automação de testes e casper jsTutorial visão automação de testes e casper js
Tutorial visão automação de testes e casper js
 
Aula javascript
Aula  javascriptAula  javascript
Aula javascript
 
Web Offline
Web OfflineWeb Offline
Web Offline
 
Oficina groovy grails - infoway
Oficina  groovy grails - infowayOficina  groovy grails - infoway
Oficina groovy grails - infoway
 
Javascript aula 01 - visão geral
Javascript   aula 01 - visão geralJavascript   aula 01 - visão geral
Javascript aula 01 - visão geral
 
Behavior Driven Development com Ruby on Rails
Behavior Driven Development com Ruby on RailsBehavior Driven Development com Ruby on Rails
Behavior Driven Development com Ruby on Rails
 
Mean Stack
Mean StackMean Stack
Mean Stack
 
XML Free Programming - Brazil
XML Free Programming - BrazilXML Free Programming - Brazil
XML Free Programming - Brazil
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpec
 
Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN Stack
 
Curso de Grails
Curso de GrailsCurso de Grails
Curso de Grails
 
Java 08
Java 08Java 08
Java 08
 
Javascript no SAPO e libsapojs
Javascript no SAPO e libsapojsJavascript no SAPO e libsapojs
Javascript no SAPO e libsapojs
 
Introdução ao Desenvolvimento de aplicações WEB com JSP
Introdução ao Desenvolvimento de aplicações WEB com JSPIntrodução ao Desenvolvimento de aplicações WEB com JSP
Introdução ao Desenvolvimento de aplicações WEB com JSP
 
Introdução a Grails: Um framework veloz e poderoso
Introdução a Grails: Um framework veloz e poderosoIntrodução a Grails: Um framework veloz e poderoso
Introdução a Grails: Um framework veloz e poderoso
 
Grails
GrailsGrails
Grails
 

Destaque

Tutorial ruby eustaquio taq rangel
Tutorial ruby   eustaquio taq rangelTutorial ruby   eustaquio taq rangel
Tutorial ruby eustaquio taq rangelWalker Maidana
 
Minicurso Ruby on Rails Dextra
Minicurso Ruby on Rails DextraMinicurso Ruby on Rails Dextra
Minicurso Ruby on Rails DextraDextra
 
Ruby and Rails for womens
Ruby and Rails for womensRuby and Rails for womens
Ruby and Rails for womenss4nx
 
Ruby - praticamente falando
Ruby - praticamente falandoRuby - praticamente falando
Ruby - praticamente falandos4nx
 

Destaque (6)

Vimbook
VimbookVimbook
Vimbook
 
Tutorial ruby eustaquio taq rangel
Tutorial ruby   eustaquio taq rangelTutorial ruby   eustaquio taq rangel
Tutorial ruby eustaquio taq rangel
 
Minicurso Ruby on Rails Dextra
Minicurso Ruby on Rails DextraMinicurso Ruby on Rails Dextra
Minicurso Ruby on Rails Dextra
 
Curso Ruby
Curso RubyCurso Ruby
Curso Ruby
 
Ruby and Rails for womens
Ruby and Rails for womensRuby and Rails for womens
Ruby and Rails for womens
 
Ruby - praticamente falando
Ruby - praticamente falandoRuby - praticamente falando
Ruby - praticamente falando
 

Semelhante a Ruby on Rails instalação

Integração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControlIntegração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControlManuel Lemos
 
Palestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAPalestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAThiago Cifani
 
LabMM3 - Aula teórica 04
LabMM3 - Aula teórica 04LabMM3 - Aula teórica 04
LabMM3 - Aula teórica 04Carlos Santos
 
PHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformancePHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformanceFelipe Ribeiro
 
Phpjedi 090307090434-phpapp01 2
Phpjedi 090307090434-phpapp01 2Phpjedi 090307090434-phpapp01 2
Phpjedi 090307090434-phpapp01 2PrinceGuru MS
 
(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - SubalgoritmosCarlos Santos
 
(A04 e A05) LabMM3 - JavaScript
(A04 e A05) LabMM3 - JavaScript(A04 e A05) LabMM3 - JavaScript
(A04 e A05) LabMM3 - JavaScriptCarlos Santos
 
Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.Alex Guido
 
Mini-curso RubyOnRails CESOL
Mini-curso RubyOnRails CESOLMini-curso RubyOnRails CESOL
Mini-curso RubyOnRails CESOLtarginosilveira
 
Spring MVC Framework
Spring MVC FrameworkSpring MVC Framework
Spring MVC Frameworkelliando dias
 
Desenvolvendo para WordPress com Docker, Git e WP-CLI
Desenvolvendo para WordPress com Docker, Git e WP-CLIDesenvolvendo para WordPress com Docker, Git e WP-CLI
Desenvolvendo para WordPress com Docker, Git e WP-CLIRudá Almeida
 
Curso de Ruby on Rails - Aula 01
Curso de Ruby on Rails - Aula 01Curso de Ruby on Rails - Aula 01
Curso de Ruby on Rails - Aula 01Maurício Linhares
 
T03_LM3: Javascript (2013-2014)
T03_LM3: Javascript (2013-2014)T03_LM3: Javascript (2013-2014)
T03_LM3: Javascript (2013-2014)Carlos Santos
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkPablo Dall'Oglio
 
Curso JavaScript - Aula de Introdução como Programar
Curso JavaScript - Aula de Introdução como ProgramarCurso JavaScript - Aula de Introdução como Programar
Curso JavaScript - Aula de Introdução como ProgramarTiago Antônio da Silva
 
ASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre TarifaASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre Tarifaguestea329c
 

Semelhante a Ruby on Rails instalação (20)

Integração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControlIntegração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControl
 
Palestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAPalestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVA
 
LabMM3 - Aula teórica 04
LabMM3 - Aula teórica 04LabMM3 - Aula teórica 04
LabMM3 - Aula teórica 04
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3
 
Oficial
OficialOficial
Oficial
 
PHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformancePHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta Performance
 
Phpjedi 090307090434-phpapp01 2
Phpjedi 090307090434-phpapp01 2Phpjedi 090307090434-phpapp01 2
Phpjedi 090307090434-phpapp01 2
 
(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos
 
(A04 e A05) LabMM3 - JavaScript
(A04 e A05) LabMM3 - JavaScript(A04 e A05) LabMM3 - JavaScript
(A04 e A05) LabMM3 - JavaScript
 
Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.
 
Mini-curso RubyOnRails CESOL
Mini-curso RubyOnRails CESOLMini-curso RubyOnRails CESOL
Mini-curso RubyOnRails CESOL
 
Spring MVC Framework
Spring MVC FrameworkSpring MVC Framework
Spring MVC Framework
 
Desenvolvendo para WordPress com Docker, Git e WP-CLI
Desenvolvendo para WordPress com Docker, Git e WP-CLIDesenvolvendo para WordPress com Docker, Git e WP-CLI
Desenvolvendo para WordPress com Docker, Git e WP-CLI
 
Curso de Ruby on Rails - Aula 01
Curso de Ruby on Rails - Aula 01Curso de Ruby on Rails - Aula 01
Curso de Ruby on Rails - Aula 01
 
T03_LM3: Javascript (2013-2014)
T03_LM3: Javascript (2013-2014)T03_LM3: Javascript (2013-2014)
T03_LM3: Javascript (2013-2014)
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
 
Apache Wicket
Apache WicketApache Wicket
Apache Wicket
 
Curso JavaScript - Aula de Introdução como Programar
Curso JavaScript - Aula de Introdução como ProgramarCurso JavaScript - Aula de Introdução como Programar
Curso JavaScript - Aula de Introdução como Programar
 
ASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre TarifaASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre Tarifa
 

Mais de elliando dias

Clojurescript slides
Clojurescript slidesClojurescript slides
Clojurescript slideselliando dias
 
Why you should be excited about ClojureScript
Why you should be excited about ClojureScriptWhy you should be excited about ClojureScript
Why you should be excited about ClojureScriptelliando dias
 
Functional Programming with Immutable Data Structures
Functional Programming with Immutable Data StructuresFunctional Programming with Immutable Data Structures
Functional Programming with Immutable Data Structureselliando dias
 
Nomenclatura e peças de container
Nomenclatura  e peças de containerNomenclatura  e peças de container
Nomenclatura e peças de containerelliando dias
 
Polyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better AgilityPolyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better Agilityelliando dias
 
Javascript Libraries
Javascript LibrariesJavascript Libraries
Javascript Librarieselliando dias
 
How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!elliando dias
 
A Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the WebA Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the Webelliando dias
 
Introdução ao Arduino
Introdução ao ArduinoIntrodução ao Arduino
Introdução ao Arduinoelliando dias
 
Incanter Data Sorcery
Incanter Data SorceryIncanter Data Sorcery
Incanter Data Sorceryelliando dias
 
Fab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine DesignFab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine Designelliando dias
 
The Digital Revolution: Machines that makes
The Digital Revolution: Machines that makesThe Digital Revolution: Machines that makes
The Digital Revolution: Machines that makeselliando dias
 
Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.elliando dias
 
Hadoop and Hive Development at Facebook
Hadoop and Hive Development at FacebookHadoop and Hive Development at Facebook
Hadoop and Hive Development at Facebookelliando dias
 
Multi-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case StudyMulti-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case Studyelliando dias
 

Mais de elliando dias (20)

Clojurescript slides
Clojurescript slidesClojurescript slides
Clojurescript slides
 
Why you should be excited about ClojureScript
Why you should be excited about ClojureScriptWhy you should be excited about ClojureScript
Why you should be excited about ClojureScript
 
Functional Programming with Immutable Data Structures
Functional Programming with Immutable Data StructuresFunctional Programming with Immutable Data Structures
Functional Programming with Immutable Data Structures
 
Nomenclatura e peças de container
Nomenclatura  e peças de containerNomenclatura  e peças de container
Nomenclatura e peças de container
 
Geometria Projetiva
Geometria ProjetivaGeometria Projetiva
Geometria Projetiva
 
Polyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better AgilityPolyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better Agility
 
Javascript Libraries
Javascript LibrariesJavascript Libraries
Javascript Libraries
 
How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!
 
Ragel talk
Ragel talkRagel talk
Ragel talk
 
A Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the WebA Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the Web
 
Introdução ao Arduino
Introdução ao ArduinoIntrodução ao Arduino
Introdução ao Arduino
 
Minicurso arduino
Minicurso arduinoMinicurso arduino
Minicurso arduino
 
Incanter Data Sorcery
Incanter Data SorceryIncanter Data Sorcery
Incanter Data Sorcery
 
Rango
RangoRango
Rango
 
Fab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine DesignFab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine Design
 
The Digital Revolution: Machines that makes
The Digital Revolution: Machines that makesThe Digital Revolution: Machines that makes
The Digital Revolution: Machines that makes
 
Hadoop + Clojure
Hadoop + ClojureHadoop + Clojure
Hadoop + Clojure
 
Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.
 
Hadoop and Hive Development at Facebook
Hadoop and Hive Development at FacebookHadoop and Hive Development at Facebook
Hadoop and Hive Development at Facebook
 
Multi-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case StudyMulti-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case Study
 

Ruby on Rails instalação

  • 1. Ruby on Rails Regis Pires Magalhães regispiresmag@gmail.com http://regispiresmag.googlepages.com Última atualização em 24/01/2007
  • 2. Instalação do Ruby 1 – No Linux - http://rubyforge.org/frs/download.php/7858/ruby- 1.8.4.tar.gz tar xvzf ruby-<versão>.tgz ./configure make make install 2 – No Windows - One-Click Installer – já vem com RubyGems: http://rubyforge.org/frs/download.php/11488/ruby184-20.exe
  • 3. Instalação do RubyGems • Desnecessário no Windows, pois já vem no One-Click Installer • RubyGems - gerenciador de pacotes do Ruby 1 – Descompactar: http://rubyforge.org/frs/download.php/11290/rubygems-0.9.0.zip 2 – Executar: ruby setup.rb
  • 4. Instalação do Rails • Via Internet: gem install rails --include-dependencies • Local: – Ir para diretório onde estão os arquivos gem e executar: gem install activesupport actionpack actionmailer activerecord actionwebservice rails –-local – Arquivos necessários: • rails-1.1.6.gem • actionmailer-1.2.5.gem • actionpack-1.12.5.gem • actionwebservice-1.1.6.gem • activerecord-1.14.4.gem • activesupport-1.3.1.gem
  • 5. Instalação do PostgreSQL • No Windows: – Descompactar: • postgresql-8.1.4-1.zip – Executar: • postgresql-8.1.msi
  • 6. Instalação da biblioteca do PostgreSQL para o Ruby • Via internet: gem install postgres-pr • Local: gem install postgres-pr –-local
  • 7. Criação do Banco de Dados create database <projeto>_<ambiente> create database livraria_development Ambientes: • Development - desenvolvimento • Test - testes • Production - produção
  • 8. Criação de tabelas • usuarios • tipos – id serial (PK) – id serial (PK) – nome varchar(75) – descricao varchar(50) – email varchar(75) – senha varchar(10) • telefones – – id serial (PK) admin int4 – – usuario_id int4 img bytea – numero varchar(10) • categorias • produtos – id serial (PK) – id serial (PK) – descricao varchar(50) – descricao varchar(100) – tipo_id int4 – categoria_id int4
  • 9. Criação do Projeto rails <projeto> >rails livraria create create app/controllers create app/helpers create app/models create app/views/layouts create config/environments create components create db create doc create lib create lib/tasks create log ...
  • 10. Configuração do acesso a banco de dados • Abrir arquivo config/database.yml: development: adapter: postgresql database: livraria_development username: postgres password: 1234 host: localhost ...
  • 11. Testando o Servidor WEB ruby script/server ruby script/server –e [development|test|production] • Development é o default.
  • 12. Geração de um Scaffold • Scaffold - tradução: andaime, palanque, armação , esqueleto • Scaffold é um meio de criar código para um determinado modelo através de um determinado controlador. • É um meio de começarmos rapidamente a ver os resultados no navegador Web e um método muito rápido de implementar o CRUD (Create, Retrieve, Update, Delete) na sua aplicação. ruby script/generate scaffold <Model> <Controller> ruby script/generate scaffold Usuario Admin::Usuario • O controlador Admin::Usuario gerenciará as ações recebidas. O rails irá criar a seguinte estrutura de diretórios: <aplicação>/controllers/admin
  • 13. Outras gerações comuns • Modelo: ruby script/generate model <Model> • Controlador: ruby script/generate controller <controller>
  • 14. Diretórios da aplicação • controllers – Classes de controle. – Uma classe controller trata uma requisição Web do usuário. – A URL da requisição Web é mapeada para uma classe de controle e para um método dentro da classe. • views – Armazena as templates de visualização para preenchimento com dados da aplicação, conversão para HTML e retorno para o browser. • models – Armazena as classes que modelam e encapsulam dos dados armazenados nos bancos de dados da aplicação. • helpers – Armazena classes de auxílio usadas para ajudar as classes model, view e controller. Ajudam a manter os códigos de model, view e controller bastante enxutos.
  • 15. Modelo <aplicação>/app/models/usuario.rb: class Usuario < ActiveRecord::Base end • A classe Usuario já é capaz de gerenciar os dados da tabela no banco de dados. • Não há necessidade de explicitar o mapeamento das colunas do banco com atributos da classe. • Rails não proíbe nada: se for necessário existe como mapear uma coluna para outro atributo de nome diferente. • Nome de tabela diferente da convenção: class EncomendaCliente < ActiveRecord::Base set_table_name quot;encomendas_clientesquot; end
  • 16. Modelo • Toda entidade é criada no diretório padrão: /app/models/<controller>/<model>.rb • Toda entidade herda diretamente da classe ActiveRecord::Base . • Não há necessidade de mapear manualmente cada coluna da tabela. • Convenção: a classe tem o nome no singular (Usuario), a tabela tem o nome do plural (usuarios). • Convenção: Toda tabela tem uma chave primária chamada id que é de tipo auto-incremento.
  • 17. Active Record Interativo ruby script/console • Toda entidade criada pode ser manipulada pelo console. • Facilita testes antes de criar as actions.
  • 18. Acrescentando validação class Usuario < ActiveRecord::Base validates_presence_of :nome validates_length_of :nome, :maximum => 75, :message => quot;Máximo de %d caracteres.quot; end Outros exemplos: validates_uniqueness_of :cpf validates_length_of :cpf, :is => 11 validates_length_of :user_name, :within => 6..20, :too_long => quot;deve ser menorquot;, :too_short => quot;deve ser maiorquot; validates_length_of :first_name, :maximum=>30
  • 19. Controller • Todo Controller fica no diretório: /app/controllers/<nome>_controller.rb • Todo Controller herda a classe ApplicationController • Todo aplicativo Rails é criado com uma classe chamada ApplicationController que herda de , ActionController::Base e é base de todos os outros , controllers • Todo método de um controller é chamado de Action • Uma classe Controller pode ter quantas Actions quanto necessárias. class Admin::UsuarioController < ApllicationController def index render :text => “Hello World!” end end
  • 20. Acessando uma Action • Roteamento Customizável (routes.rb) http://localhost:3000/:controller/:action/:id • Exemplo: http://localhost:3000/blog/index • blog = app/controller/blog_controller.rb • index = método index em BlogController
  • 22. Mais convenções • Ao final de toda Action, Rails chamará uma view com o mesmo nome da Action, no seguinte diretório: /app/views/<controller>/<action>.<ext> • A extensão do arquivo pode ser: – .rhtml - Embedded Ruby (HTML+Ruby) – .rxml - XML Builder (Ruby puro) – .rjs - Javascript Generator (Ruby puro) • Este fluxo pode ser interrompido com uma chamada explícita ao método render ou redirect_to.
  • 23. Modificando a listagem /app/views/admin/usuario/list.rhtml • Podemos alterar o layout ou qualquer código como quisermos.
  • 24. Layouts • Layouts permitem o compartilhamento de conteúdo. • Todo novo controller automaticamente ganha um layout no diretório: /app/views/layouts/<controller>.rhtml • As views desse controller preenchem o espaço: <%= @content_for_layout %>
  • 25. Layouts # test_controller.rb class TestController < ApplicationController layout quot;defaultquot; def index end end <!-- default.rhtml --> <html> <head> <title>Teste</title> </head> <body> <h1>Layout Padrao</h1> <%= @content_for_layout %> </body> </html>
  • 26. Scriptlets <% @usuarios.each do |usuario| %> Faz alguma coisa com usuario <% end %> ... <% if number == quot;7quot; %> Está correto! <% end %>
  • 27. Flash • flash[:notice] está disponível somente naquela requisição. Usado para comunicação entre ações: passagem de string contendo informação ou erro. • Similar a variáveis de sessão, mas somente existe de uma página para outra. Uma vez que a requisição para a qual foram propagadas acaba, elas são automaticamente removidas do contexto de execução. def three flash[:notice] => quot;Helloquot; flash[:warning] => quot;Mewlquot; flash[:error] => quot;Erro!quot; render end
  • 28. Logger • Nível de log configurado em: config/environment.rb: config.log_level = :debug • Mensagens escritas em um arquivo no diretório log. O arquivo de log usado depende do ambiente (environment) usado pela aplicação. Ex.: log/development.log logger.warn(quot;I don't think that's a good ideaquot; ) logger.info(quot;Dave's trying to do something badquot; ) logger.error(quot;Now he's gone and broken itquot; ) logger.fatal(quot;I give upquot; )
  • 29. Paginação • Para todas as ações do Controller: class PersonController < ApplicationController model :person paginate :people, :order => 'last_name, first_name', :per_page => 20 # ... end
  • 30. Paginação • Para uma única ação do Controller: def list @person_pages, @people = paginate :people, :order => 'last_name, first_name' end
  • 31. Paginação • Condicional @upcoming_event_pages, @upcoming_events = paginate :upcoming_event, :conditions => quot;event LIKE '%quot;params['upcoming_event']['search'].to_squot;%'quot;, :order_by => quot;date DESCquot;, :per_page => 10
  • 32. Paginação • Genérica def list @person_pages = Paginator.new self, Person.count, 10, params[:page] @people = Person.find :all, :order => 'last_name, first_name', :limit => @person_pages.items_per_page, :offset => @person_pages.current.offset end
  • 33. Paginação • paginate(collection_id, options={}) – Retorna um paginator e uma coleção de instâncias de modelo Active Record para a página atual. • Opções: – :singular_name: the singular name to use, if it can‘t be inferred by singularizing the collection name – :class_name: the class name to use, if it can‘t be inferred by camelizing the singular name – :per_page: the maximum number of items to include in a single page. Defaults to 10 – :conditions: optional conditions passed to Model.find(:all, *params) and Model.count – :order: optional order parameter passed to Model.find(:all, *params) – :order_by: (deprecated, used :order) optional order parameter passed to Model.find(:all, *params) – :joins: optional joins parameter passed to Model.find(:all, *params) and Model.count – :join: (deprecated, used :joins or :include) optional join parameter passed to Model.find(:all, *params) and Model.count – :include: optional eager loading parameter passed to Model.find(:all, *params) and Model.count – :select: :select parameter passed to Model.find(:all, *params) – :count: parameter passed as :select option to Model.count(*params)
  • 34. Paginação • Em um array / collection: def paginate_collection(collection, options = {}) default_options = {:per_page => 10, :page => 1} options = default_options.merge options pages = Paginator.new self, collection.size, options[:per_page], options[:page] first = pages.current.offset last = [first + options[:per_page], collection.size].min slice = collection[first...last] return [pages, slice] end @pages, @users = paginate_collection User.find_custom_query, :page => @params[:page]
  • 38. Associações • Todo usuario pode ter vários telefones. • Telefone pertence a Usuario através da coluna usuario_id. • Convenção de Chave Estrangeira: <classe>_id class Usuario < ActiveRecord::Base has_many :telefones # um usuário tem muitos telefones validates_presence_of :nome validates_length_of :nome, :maximum => 75, :message => quot;Máximo de %d caracteres.quot; end class Telefone < ActiveRecord::Base belongs_to :usuario # um telefone pertence a um usuário end
  • 43. Rake • Programa em Ruby para realizar um conjunto de tarefas (tasks). • Cada tarefa tem um nome, uma lista de tarefas das quais ela depende e uma lista de ações a realizar. • Para ver as tarefas existentes em um arquivo rake (Rakefile): rake --tasks
  • 44. Testes Unitários • Toda nova entidade ganha um arquivo para teste unitário em: /app/test/unit/<entidade>_test.rb • Devemos seguir os preceitos de Test-Driven Development: “Se não vale a pena testar, para que estamos codificando?” • Os testes acontecem em banco de dados separado do desenvolvimento <projeto>_test • Cada teste roda de maneira isolada: os dados modificados em um teste não afetam outro teste • Cada teste unitário tem um arquivo de “fixture”, carga de dados para testes: /app/test/fixture/<tabela>.yml • Executando todos os testes unitários rake test:units • Executando apenas um teste unitário: ruby test/unit/<entidade>_test.rb
  • 45. Testes Unitários require File.dirname(__FILE__) + '/../test_helper' class PostTest < Test::Unit::TestCase fixtures :posts # Replace this with your real tests. def test_add_comment # adiciona um post @post = Post.create(:title => 'New Post', :body => 'New Post', :author => 'Anonymous') # adiciona um comment @comment = @post.comments.create(:body => 'New Comment', :author => 'Anonymous') assert_not_equal nil, @comment # recarrega a entidade @post.reload # checa se existe apenas um post assert_equal 3, Post.count # já existem 2 posts na fixture # checa se esse post tem apenas um comment assert_equal 1, @post.comments.count end end
  • 46. Fixture YAML • “YAML Ain’t a Markup Language” • Maneira de serializar objetos Ruby em forma de texto • Formato humanamente legível • Mais leve e simples que XML
  • 47. Fixture YAML # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html ronaldo: id: 1 name: Ronaldo login: ronaldo admin: true email: ronaldo@reflectivesurface.com data: 2004-07-01 00:00:00 hashed_password: <%= Digest::SHA1.hexdigest('abracadabra') %> marcus: id: 2 name: Marcus login: marcus admin: false email: marcus@reflectivesurface.com data: <%= 1.day.from_now.strftime(quot;%Y-%m-%dquot;) %> hashed_password: <%= Digest::SHA1.hexdigest('teste') %>
  • 53. Testes Funcionais • Todo novo controller ganha uma classe de teste em: /app/test/functional/<classe>_controller_test.rb • Devemos testar cada action do controller • Métodos como get e post simulam navegação com um browser • Executando todos os testes funcionais: rake test:functionals • Executando apenas um testes funcional: ruby test/functional/<classe>_controller_test.rb
  • 54. Testes Funcionais require File.dirname(__FILE__) + '/../test_helper' require 'blog_controller' # Re-raise errors caught by the controller. class BlogController; def rescue_action(e) raise e end; end class BlogControllerTest < Test::Unit::TestCase fixtures :posts def setup @controller = BlogController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end def test_create num_posts = Post.count # checa total de posts atual # simula submit do formulário de criar novo post post :create, :post => {:title => 'New Title', :body => 'New Post', :author => 'Anonymous'} # checa se depois da action fomos redirecionados assert_response :redirect # checa se realmente foi acrescentado um novo post assert_equal num_posts + 1, Post.count end end
  • 55. Testes Funcionais require File.dirname(__FILE__) + '/../test_helper' require 'users_controller' # Re-raise errors caught by the controller. class UsersController; def rescue_action(e) raise e end; end class UsersControllerTest < Test::Unit::TestCase fixtures :users def setup @controller = UsersController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end def test_index get :index assert_redirected_to :controller => quot;loginquot;, :action => quot;loginquot; end def test_index_with_login @request.session[:user] = users(:ronaldo).id get :index assert_response :success assert_tag :tag => quot;tablequot;, :children => { :count => User.count + 1, :only => { :tag => quot;trquot; } } assert_tag :tag => quot;tdquot;, :content => users(:ronaldo).name end end
  • 58. Testes de Integração • Para gerar o teste: script/generate integration_test login • Para executar o teste: rake test:integration
  • 59. Testes de Integração require quot;#{File.dirname(__FILE__)}/../test_helperquot; class LoginTest < ActionController::IntegrationTest fixtures :users def test_login user = users(:ronaldo) get quot;/homequot; assert_redirected_to quot;/login/loginquot; follow_redirect! assert_response :success post quot;/login/loginquot; assert_response :success assert_equal quot;Invalid login and/or password.quot;, flash[:notice] post quot;/login/loginquot;, :login => user.login, :password => user.password assert_redirected_to quot;/homequot; follow_redirect! assert_tag :tag => quot;divquot;, :attributes => { :id => quot;edit_formquot; } end end
  • 61. Mais Testes • Testes Unitários devem testar todos os aspectos da entidade como associações, validações, callbacks, etc • Testes Funcionais devem testar todas as actions de um mesmo controller, todos os fluxos, redirecionamentos, filtros, etc • Testes Integrados servem para avaliar a navegação e fluxos entre actions de diferentes controllers. Funcionam de maneira semelhante a um teste funcional
  • 62. Helpers # Global helper para views. module ApplicationHelper # Formata um float com duas casa decimais def fmt_decimal(valor, decimais) sprintf(quot;%0.#{decimais}fquot; valor) , end end
  • 63. O que NÃO fizemos • Não precisamos recompilar e reinstalar o aplicativo a cada mudança. • Não precisamos reiniciar o servidor a cada mudança. • Não precisamos mapear cada uma das colunas das tabelas para as entidades. • Não precisamos configurar dezenas de arquivos XML. Basicamente colocamos a senha do banco de dados, apenas. • Não precisamos usar Javascript para fazer Ajax: a maior parte pode ser feita com Ruby puro. • Não sentimos falta de taglibs: expressões Ruby, partials foram simples o suficiente. • Não precisamos codificar código-cola, o framework possui “padrões espertos” afinal, todo aplicativo Web tem a mesma infraestrutura.
  • 64. Referências • Agile Web Development with Rails. 2ª Edição. – Thomas e David Heinemeier Hansson. • Entendendo Rails – Fábio Akita (http://www.esnips.com/web/BalanceOnRails) • Creating a weblog in 15 minutes – http://media.rubyonrails.org/video/rails_take2_with_sound.mov • Tutorial de Rails do TaQ – http://www.eustaquiorangel.com/downloads/tutorialrails.pdf • Tutorial de Ruby on Rails do Ronaldo Ferraz – http://kb.reflectivesurface.com/br/tutoriais/rubyOnRails • Rolling with Ruby on Rails by Curt Hibbs – http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html • Tutorial de Ruby do TaQ – http://www.eustaquiorangel.com/downloads/tutorialruby.pdf