SlideShare une entreprise Scribd logo
1  sur  192
Télécharger pour lire hors ligne
Ruby on Rails
Friday, August 7, 2009
AkitaOnRails.com
            slideshare.net/akitaonrails




Friday, August 7, 2009
2008
Friday, August 7, 2009
2008
Friday, August 7, 2009
13 e 14
                         Outubro

                         2009
Friday, August 7, 2009
Friday, August 7, 2009
~140 slides
                          ~45 min


Friday, August 7, 2009
www.slideshare.net/akitaonrails

                     fabio.akita@locaweb.com.br




Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Ruby on Rails         2.3

                         Ruby   1.8

                 Novo Ruby      1.9
Friday, August 7, 2009
Ruby on Rails         2.3

                         Ruby   1.8

                 Novo Ruby      1.9
Friday, August 7, 2009
Ruby on Rails         2.3

                         Ruby   1.8

                 Novo Ruby      1.9
Friday, August 7, 2009
“Matz”




                         1993
Friday, August 7, 2009
Friday, August 7, 2009
“Prag Dave”




                         2001
Friday, August 7, 2009
Friday, August 7, 2009
“DHH”



                          2004
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Charles Nutter



                              2006
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
“Tornar as coisas
               simples fáceis e as
                coisas complexas
                    possíveis”
                         Filosofia Ruby

Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
O que dizem
                           por aí ...


Friday, August 7, 2009
Pouco usado



Friday, August 7, 2009
Rails não Escala



Friday, August 7, 2009
Ruby é Lento



Friday, August 7, 2009
WTF!?

Friday, August 7, 2009
Pouco usado



Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Rails não Escala



Friday, August 7, 2009
Friday, August 7, 2009
Blaine Cook

                         http://www.akitaonrails.com/2008/6/17/chatting-with-blaine-cook-twitter


Friday, August 7, 2009
Para colocar as coisas em
      perspectiva, o Friendster foi
          escrito em Java e eles
      mudaram para PHP. MySpace
      foi escrito em ColdFusion e
      eles mudaram para ASP.NET.




                                                                              Blaine Cook

                         http://www.akitaonrails.com/2008/6/17/chatting-with-blaine-cook-twitter


Friday, August 7, 2009
Para colocar as coisas em
      perspectiva, o Friendster foi
          escrito em Java e eles
      mudaram para PHP. MySpace
      foi escrito em ColdFusion e
      eles mudaram para ASP.NET.

      Quando as pessoas caem em
       problemas de escalabilidade,
        normalmente acham que a
      linguagem é o problema, mas
       eu acho que isso raramente
              é a realidade.                                                  Blaine Cook

                         http://www.akitaonrails.com/2008/6/17/chatting-with-blaine-cook-twitter


Friday, August 7, 2009
“O The New York Times usou Ruby on Rails para
               agregar, analizar e mostrar os resultados das
             eleições em quase tempo real em um de seus
              sites mais acessados de todos os tempos.”



                         http://www.computerworld.com.au/article/268003/ruby_rails_rolls_into_enterprise?fp=16&fpid=1




Friday, August 7, 2009
“O The New York Times usou Ruby on Rails para
               agregar, analizar e mostrar os resultados das
             eleições em quase tempo real em um de seus
              sites mais acessados de todos os tempos.”



                         http://www.computerworld.com.au/article/268003/ruby_rails_rolls_into_enterprise?fp=16&fpid=1




Friday, August 7, 2009
Ruby é Lento



Friday, August 7, 2009
x mais lento que C++




Friday, August 7, 2009
x mais lento que C++
                         0
                             50
                                           100
     Python 2                                            150

       Ruby 1.9                                                200

              Perl

            JRuby

         Python 3

                PHP

          Ruby 1.8.6




Friday, August 7, 2009
Homepage: 331 ms




Friday, August 7, 2009
Homepage: 331 ms

                         Total: 5.45 s
Friday, August 7, 2009
Friday, August 7, 2009
Performance
                              !=
                         Escalabilidade

Friday, August 7, 2009
Ruby on Rails



Friday, August 7, 2009
Friday, August 7, 2009
Código que gera Código


                 Convention over Configuration


                          Don’t Repeat Yourself


                         Extreme Programming

Friday, August 7, 2009
Código que gera Código


                 Convention over Configuration


                          Don’t Repeat Yourself


                         Extreme Programming

Friday, August 7, 2009
Código que gera Código


                 Convention over Configuration


                          Don’t Repeat Yourself


                         Extreme Programming

Friday, August 7, 2009
Código que gera Código


                 Convention over Configuration


                          Don’t Repeat Yourself


                         Extreme Programming

Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Model

   class Product < ActiveRecord::Base
     after_create :set_initial_inventory

       has_many :variants, :dependent => :destroy
       has_many :images, :as => :viewable, :order => :position,
         :dependent => :destroy
       has_many :properties, :through => :product_properties
       belongs_to :tax_category

       validates_presence_of :name
       validates_presence_of :master_price
       validates_presence_of :description

     make_permalink :with => :name, :field => :permalink
   end




Friday, August 7, 2009
Model

   class Product < ActiveRecord::Base
     after_create :set_initial_inventory

       has_many :variants, :dependent => :destroy
       has_many :images, :as => :viewable, :order => :position,
         :dependent => :destroy
       has_many :properties, :through => :product_properties
       belongs_to :tax_category

       validates_presence_of :name
       validates_presence_of :master_price
       validates_presence_of :description

     make_permalink :with => :name, :field => :permalink
   end




Friday, August 7, 2009
Model

   class Product < ActiveRecord::Base
     after_create :set_initial_inventory

       has_many :variants, :dependent => :destroy
       has_many :images, :as => :viewable, :order => :position,
         :dependent => :destroy
       has_many :properties, :through => :product_properties
       belongs_to :tax_category

       validates_presence_of :name
       validates_presence_of :master_price
       validates_presence_of :description

     make_permalink :with => :name, :field => :permalink
   end




Friday, August 7, 2009
Model

   class Product < ActiveRecord::Base
     after_create :set_initial_inventory

       has_many :variants, :dependent => :destroy
       has_many :images, :as => :viewable, :order => :position,
         :dependent => :destroy
       has_many :properties, :through => :product_properties
       belongs_to :tax_category

       validates_presence_of :name
       validates_presence_of :master_price
       validates_presence_of :description

     make_permalink :with => :name, :field => :permalink
   end




Friday, August 7, 2009
Model

   class Product < ActiveRecord::Base
     after_create :set_initial_inventory

       has_many :variants, :dependent => :destroy
       has_many :images, :as => :viewable, :order => :position,
         :dependent => :destroy
       has_many :properties, :through => :product_properties
       belongs_to :tax_category

       validates_presence_of :name
       validates_presence_of :master_price
       validates_presence_of :description

     make_permalink :with => :name, :field => :permalink
   end




Friday, August 7, 2009
Model

   class Product < ActiveRecord::Base
     after_create :set_initial_inventory

       has_many :variants, :dependent => :destroy
       has_many :images, :as => :viewable, :order => :position,
         :dependent => :destroy
       has_many :properties, :through => :product_properties
       belongs_to :tax_category

       validates_presence_of :name
       validates_presence_of :master_price
       validates_presence_of :description

     make_permalink :with => :name, :field => :permalink
   end




Friday, August 7, 2009
Model

   class Product < ActiveRecord::Base
     after_create :set_initial_inventory

       has_many :variants, :dependent => :destroy
       has_many :images, :as => :viewable, :order => :position,
         :dependent => :destroy
       has_many :properties, :through => :product_properties
       belongs_to :tax_category

       validates_presence_of :name
       validates_presence_of :master_price
       validates_presence_of :description

     make_permalink :with => :name, :field => :permalink
   end




Friday, August 7, 2009
Model

   class Product < ActiveRecord::Base
     after_create :set_initial_inventory

       has_many :variants, :dependent => :destroy
       has_many :images, :as => :viewable, :order => :position,
         :dependent => :destroy
       has_many :properties, :through => :product_properties
       belongs_to :tax_category

       validates_presence_of :name
       validates_presence_of :master_price
       validates_presence_of :description

     make_permalink :with => :name, :field => :permalink
   end




Friday, August 7, 2009
Model

   class Product < ActiveRecord::Base
     after_create :set_initial_inventory

       has_many :variants, :dependent => :destroy
       has_many :images, :as => :viewable, :order => :position,
         :dependent => :destroy
       has_many :properties, :through => :product_properties
                        Product.find(1)
       belongs_to :tax_category

       validates_presence_of :name
       validates_presence_of :master_price
       validates_presence_of :description

     make_permalink :with => :name, :field => :permalink
   end




Friday, August 7, 2009
Views ERB
   <div id="product-listing">
     <%= breadcrumbs(@taxon) %>
     <br/>
     <%= render :partial => "shared/products.html.erb",
     :locals => {:products => @products, :taxon => @taxon } %>
   </div>

   <% content_for :sidebar do %>
     <td id="shop-by-col" valign="top">
       <%= render :partial => "shared/taxonomies" %>
     </td>
   <% end %>

   <%= render :partial => 'shared/paginate',
     :locals => {:collection => @products, :options => {}}
     unless @products.empty? %>



Friday, August 7, 2009
Views ERB
   <div id="product-listing">
     <%= breadcrumbs(@taxon) %>
     <br/>
     <%= render :partial => "shared/products.html.erb",
     :locals => {:products => @products, :taxon => @taxon } %>
   </div>

   <% content_for :sidebar do %>
     <td id="shop-by-col" valign="top">
       <%= render :partial => "shared/taxonomies" %>
     </td>
   <% end %>

   <%= render :partial => 'shared/paginate',
     :locals => {:collection => @products, :options => {}}
     unless @products.empty? %>



Friday, August 7, 2009
Views ERB
   <div id="product-listing">
     <%= breadcrumbs(@taxon) %>
     <br/>
     <%= render :partial => "shared/products.html.erb",
     :locals => {:products => @products, :taxon => @taxon } %>
   </div>

   <% content_for :sidebar do %>
     <td id="shop-by-col" valign="top">
       <%= render :partial => "shared/taxonomies" %>
     </td>
   <% end %>

   <%= render :partial => 'shared/paginate',
     :locals => {:collection => @products, :options => {}}
     unless @products.empty? %>



Friday, August 7, 2009
Rotas RESTFul



   ActionController::Routing::Routes.draw do |map|

       map.resources :products
       map.resources :addresses
       map.resources :orders,     :has_many => [:line_items]

     map.namespace :admin do |admin|
       admin.resources :users
       admin.resources :products
     end
   end




Friday, August 7, 2009
Rotas RESTFul



   ActionController::Routing::Routes.draw do |map|

       map.resources :products
       map.resources :addresses
       map.resources :orders,     :has_many => [:line_items]

     map.namespace :admin do |admin|
       admin.resources :users
       admin.resources :products
     end
   end




Friday, August 7, 2009
Rotas RESTFul



   ActionController::Routing::Routes.draw do |map|

       map.resources :products
       map.resources :addresses
       map.resources :orders,     :has_many => [:line_items]

     map.namespace :admin do |admin|
       admin.resources :users
       admin.resources :products
     end
   end




Friday, August 7, 2009
Rotas RESTFul



   ActionController::Routing::Routes.draw do |map|

       map.resources :products
       map.resources :addresses
       map.resources :orders,     :has_many => [:line_items]

     map.namespace :admin do |admin|
       admin.resources :users
       admin.resources :products
     end
   end




Friday, August 7, 2009
Rotas RESTFul



                  GET /products/new
   ActionController::Routing::Routes.draw do |map|
                  GET /products
                  POST /products
     map.resources :products
     map.resources :addresses
     map.resourcesGET /products/1 => [:line_items]
                   :orders,    :has_many

     map.namespaceGET /products/1/edit
                   :admin do |admin|
                  PUT /products/1
       admin.resources :users
       admin.resources :products
     end          DESTROY /products/1
   end




Friday, August 7, 2009
Controller

    class UsersController < Spree::BaseController
      resource_controller
      before_filter :initialize_extension_partials
      actions :all, :except => [:index, :destroy]

         show.before do
           @orders = Order.checkout_completed(true)
             .find_all_by_user_id(current_user.id)
         end

         create.after {   self.current_user = @user }

      create.response do |wants|
        wants.html { redirect_back_or_default(products_path) }
      end
    end


Friday, August 7, 2009
Controller

    class UsersController < Spree::BaseController
      resource_controller
      before_filter :initialize_extension_partials
      actions :all, :except => [:index, :destroy]

         show.before do
           @orders = Order.checkout_completed(true)
             .find_all_by_user_id(current_user.id)
         end

         create.after {   self.current_user = @user }

      create.response do |wants|
        wants.html { redirect_back_or_default(products_path) }
      end
    end


Friday, August 7, 2009
Controller

    class UsersController < Spree::BaseController
      resource_controller
      before_filter :initialize_extension_partials
      actions :all, :except => [:index, :destroy]

         show.before do
           @orders = Order.checkout_completed(true)
             .find_all_by_user_id(current_user.id)
         end

         create.after {   self.current_user = @user }

      create.response do |wants|
        wants.html { redirect_back_or_default(products_path) }
      end
    end


Friday, August 7, 2009
Controller

    class UsersController < Spree::BaseController
      resource_controller
      before_filter :initialize_extension_partials
      actions :all, :except => [:index, :destroy]

         show.before do
           @orders = Order.checkout_completed(true)
             .find_all_by_user_id(current_user.id)
         end

         create.after {   self.current_user = @user }

      create.response do |wants|
        wants.html { redirect_back_or_default(products_path) }
      end
    end


Friday, August 7, 2009
Controller

    class UsersController < Spree::BaseController
      resource_controller
      before_filter :initialize_extension_partials
      actions :all, :except => [:index, :destroy]

         show.before do
           @orders = Order.checkout_completed(true)
                               /users/1
             .find_all_by_user_id(current_user.id)
         end

         create.after {   self.current_user = @user }

      create.response do |wants|
        wants.html { redirect_back_or_default(products_path) }
      end
    end


Friday, August 7, 2009
Migrations


        class RenameAppConfiguration < ActiveRecord::Migration
          def self.up
            rename_table :app_configurations, :configurations
            change_table :configurations do |t|
              t.string :type
            end
          end

          def self.down
            change_table :configurations do |t|
              t.remove :type
            end
            rename_table :configurations, :app_configurations
          end
        end


Friday, August 7, 2009
Migrations


        class RenameAppConfiguration < ActiveRecord::Migration
          def self.up
            rename_table :app_configurations, :configurations
            change_table :configurations do |t|
              t.string :type
            end
          end

          def self.down
            change_table :configurations do |t|
              t.remove :type
            end
            rename_table :configurations, :app_configurations
          end
        end


Friday, August 7, 2009
Migrations


        class RenameAppConfiguration < ActiveRecord::Migration
          def self.up
            rename_table :app_configurations, :configurations
            change_table :configurations do |t|
              t.string :type
            end
          end

          def self.down
            change_table :configurations do |t|
              t.remove :type
            end
            rename_table :configurations, :app_configurations
          end
        end


Friday, August 7, 2009
Migrations


        class RenameAppConfiguration < ActiveRecord::Migration
          def self.up
            rename_table :app_configurations, :configurations
            change_table :configurations do |t|
              t.string :type
            end
          end

          def self.down
            change_table :configurations do |t|
              t.remove :type
            end
            rename_table :configurations, :app_configurations
          end
        end


Friday, August 7, 2009
Migrations


        class RenameAppConfiguration < ActiveRecord::Migration
          def self.up
            rename_table :app_configurations, :configurations
            change_table :configurations do |t|
              t.string :type
            end
          end           rake db:migrate

          def self.down
            change_table :configurations do |t|
              t.remove :type
            end
            rename_table :configurations, :app_configurations
          end
        end


Friday, August 7, 2009
Open Source



Friday, August 7, 2009
Friday, August 7, 2009
describe BankAccount do
           before :each do
             @bank_account = BankAccount.new :balance => 250
           end

              it "should not be valid" do
                @bank_account.should be_valid
              end

           it "should transfer funds successfully" do
             @bank_account.should_receive(:transfer)
               .with_args(:amount => 100)
               .and_return(true)
             @bank_account.execute_transaction(:amount => 100)
             @bank_account.balance.should == 150
           end
         end


Friday, August 7, 2009
describe BankAccount do
           before :each do
             @bank_account = BankAccount.new :balance => 250
           end

              it "should not be valid" do
                @bank_account.should be_valid
              end

           it "should transfer funds successfully" do
             @bank_account.should_receive(:transfer)
               .with_args(:amount => 100)
               .and_return(true)
             @bank_account.execute_transaction(:amount => 100)
             @bank_account.balance.should == 150
           end
         end


Friday, August 7, 2009
describe BankAccount do
           before :each do
             @bank_account = BankAccount.new :balance => 250
           end

              it "should not be valid" do
                @bank_account.should be_valid
              end

           it "should transfer funds successfully" do
             @bank_account.should_receive(:transfer)
               .with_args(:amount => 100)
               .and_return(true)
             @bank_account.execute_transaction(:amount => 100)
             @bank_account.balance.should == 150
           end
         end


Friday, August 7, 2009
describe BankAccount do
           before :each do
             @bank_account = BankAccount.new :balance => 250
           end

              it "should not be valid" do
                @bank_account.should be_valid
              end

           it "should transfer funds successfully" do
             @bank_account.should_receive(:transfer)
               .with_args(:amount => 100)
               .and_return(true)
             @bank_account.execute_transaction(:amount => 100)
             @bank_account.balance.should == 150
           end
         end


Friday, August 7, 2009
Friday, August 7, 2009
Funcionalidade: Adição
                Para evitar erros bobos
                Como um péssimo matemático
                Eu quero saber como somar dois números

                   Cenário: Adicionar dois números
                     Dado que eu digitei 50 na calculadora
                     E que eu digitei 70 na calculadora
                     Quando eu aperto o botão de soma
                     Então o resultado na calculadora deve ser 120




Friday, August 7, 2009
Funcionalidade: Adição
                Para evitar erros bobos
                Como um péssimo matemático
                Eu quero saber como somar dois números

                   Cenário: Adicionar dois números
                     Dado que eu digitei 50 na calculadora
                     E que eu digitei 70 na calculadora
                     Quando eu aperto o botão de soma
                     Então o resultado na calculadora deve ser 120




Friday, August 7, 2009
Before do
   @calc = Calculadora.new
 end

 Dado /que eu digitei (d+) na calculadora/ do |n|
   @calc.push n.to_i
 end

 Quando 'eu aperto o botão de soma' do
   @result = @calc.soma
 end

 Então /o resultado na calculadora deve ser (d*)/ do |result|
   @result.should == result.to_i
 end




Friday, August 7, 2009
Before do
   @calc = Calculadora.new
 end

 Dado /que eu digitei (d+) na calculadora/ do |n|
   @calc.push n.to_i
 end

 Quando 'eu aperto o botão de soma' do
   @result = @calc.soma
 end

 Então /o resultado na calculadora deve ser (d*)/ do |result|
   @result.should == result.to_i
 end




Friday, August 7, 2009
Before do
   @calc = Calculadora.new
 end

 Dado /que eu digitei (d+) na calculadora/ do |n|
   @calc.push n.to_i
 end

 Quando 'eu aperto o botão de soma' do
   @result = @calc.soma
 end

 Então /o resultado na calculadora deve ser (d*)/ do |result|
   @result.should == result.to_i
 end




Friday, August 7, 2009
Before do
   @calc = Calculadora.new
 end

 Dado /que eu digitei (d+) na calculadora/ do |n|
   @calc.push n.to_i
 end

 Quando 'eu aperto o botão de soma' do
   @result = @calc.soma
 end

 Então /o resultado na calculadora deve ser (d*)/ do |result|
   @result.should == result.to_i
 end




Friday, August 7, 2009
class SignupTest < ActionController::IntegrationTest

               def test_trial_account_sign_up
                 visit home_path
                 click_link "Sign up"
                 fill_in "Email", :with => "good@example.com"
                 select "Free account"
                 click_button "Register"
               end

           end




Friday, August 7, 2009
Friday, August 7, 2009
rspec             rspec.info

            cucumber                cukes.info

               shoulda    thoughtbot.com/projects/shoulda

                webrat      github.com/brynary/webrat

              integrity          integrityapp.com

              ZenTest             zenspider.com


Friday, August 7, 2009
• plugins de Active Record
                • plugins de Views
                • plugins de Localização
                • CMS
                • Parsers
                • Autenticadores/Autorizadores

Friday, August 7, 2009
“Beautiful Code”



Friday, August 7, 2009
@Transient
                                                                 public BigDecimal getTotal()
       //$Id: Booking.java 5579 2007-06-27 00:06:49Z gavin $     {
       package org.jboss.seam.example.booking;                      return hotel.getPrice().multiply( new BigDecimal( getNights() ) );
                                                                 }
       import   java.io.Serializable;
       import   java.math.BigDecimal;                             @Transient
       import   java.text.DateFormat;                             public int getNights()
       import   java.util.Date;                                   {
                                                                     return (int) ( checkoutDate.getTime() - checkinDate.getTime() ) /
       import   javax.persistence.Basic;                       1000 / 60 / 60 / 24;
       import   javax.persistence.Entity;                         }
       import   javax.persistence.GeneratedValue;
       import   javax.persistence.Id;                            @Id @GeneratedValue
       import   javax.persistence.ManyToOne;                     public Long getId()
       import   javax.persistence.Temporal;                      {
       import   javax.persistence.TemporalType;                     return id;
       import   javax.persistence.Transient;                     }
                                                                 public void setId(Long id)
       import   org.hibernate.validator.Length;                  {
       import   org.hibernate.validator.NotNull;                    this.id = id;
       import   org.hibernate.validator.Pattern;                 }
       import   org.jboss.seam.annotations.Name;
                                                                 @NotNull
       @Entity                                                   @Basic @Temporal(TemporalType.DATE)
       @Name("booking")                                          public Date getCheckinDate()
       public class Booking implements Serializable              {
       {                                                            return checkinDate;
          private Long id;                                       }
          private User user;                                     public void setCheckinDate(Date datetime)
          private Hotel hotel;                                   {
          private Date checkinDate;                                 this.checkinDate = datetime;
          private Date checkoutDate;                             }
          private String creditCard;
          private String creditCardName;                         @ManyToOne @NotNull
          private int creditCardExpiryMonth;                     public Hotel getHotel()
          private int creditCardExpiryYear;                      {
          private boolean smoking;                                  return hotel;
          private int beds;                                      }
                                                                 public void setHotel(Hotel hotel)
          public Booking() {}                                    {
                                                                    this.hotel = hotel;
          public Booking(Hotel hotel, User user)                 }
          {
             this.hotel = hotel;                                 @ManyToOne @NotNull
             this.user = user;                                   public User getUser()
          }                                                      {
                                                                    return user;
                                                                 }

Friday, August 7, 2009
public int getBeds()
  public void setUser(User user)
                                                                                  {
  {
                                                                                     return beds;
     this.user = user;
                                                                                  }
  }

                                                                                  public void setBeds(int beds)
  @Basic @Temporal(TemporalType.DATE)
                                                                                  {
  @NotNull
                                                                                     this.beds = beds;
  public Date getCheckoutDate()
                                                                                  }
  {
                                                                                  @NotNull(message="Credit card name is required")
     return checkoutDate;
                                                                                  @Length(min=3, max=70, message="Credit card name is required")
  }
                                                                                  public String getCreditCardName()
  public void setCheckoutDate(Date checkoutDate)
                                                                                  {
  {
                                                                                     return creditCardName;
     this.checkoutDate = checkoutDate;
                                                                                  }
  }

                                                                                  public void setCreditCardName(String creditCardName)
  @NotNull(message="Credit card number is required")
                                                                                  {
  @Length(min=16, max=16, message="Credit card number must 16 digits long")
                                                                                     this.creditCardName = creditCardName;
  @Pattern(regex="^d*$", message="Credit card number must be numeric")
                                                                                  }
  public String getCreditCard()
  {
                                                                                  public int getCreditCardExpiryMonth()
     return creditCard;
                                                                                  {
  }
                                                                                     return creditCardExpiryMonth;
                                                                                  }
  public void setCreditCard(String creditCard)
  {
                                                                                  public void setCreditCardExpiryMonth(int creditCardExpiryMonth)
     this.creditCard = creditCard;
                                                                                  {
  }
                                                                                     this.creditCardExpiryMonth = creditCardExpiryMonth;
                                                                                  }
  @Transient
  public String getDescription()
                                                                                  public int getCreditCardExpiryYear()
  {
                                                                                  {
     DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
                                                                                     return creditCardExpiryYear;
     return hotel==null ? null : hotel.getName() +
                                                                                  }
           ", " + df.format( getCheckinDate() ) +
           " to " + df.format( getCheckoutDate() );
                                                                                  public void setCreditCardExpiryYear(int creditCardExpiryYear)
  }
                                                                                  {
                                                                                     this.creditCardExpiryYear = creditCardExpiryYear;
  public boolean isSmoking()
                                                                                  }
  {
     return smoking;
                                                                                  @Override
  }
                                                                                  public String toString()
                                                                                  {
  public void setSmoking(boolean smoking)
                                                                                     return "Booking(" + user + ","+ hotel + ")";
  {
                                                                                  }
     this.smoking = smoking;
  }
                                                                              }


Friday, August 7, 2009
class Booking < ActiveRecord::Base
                belongs_to :hotel
                belongs_to :user
                validates_presence_of :hotel
                validates_presence_of :user
                validates_presence_of :credit_card
                validates_presence_of :credit_card_name
                validates_length_of :credit_card, :within => 16..16
                validates_format_of :credit_card, :with => /^d*$/
                validates_length_of :credit_card_name, :within => 3..70

                  def total
                    hotel.price * nights
                  end

                  def nights
                    ((checkout_date - checkin_date) / 1.day).round
                  end

                def to_s
                  "Booking(#{user},#{hotel})"
                end
              end
Friday, August 7, 2009
class Booking < ActiveRecord::Base
                belongs_to :hotel
                belongs_to :user
                validates_presence_of :hotel
                validates_presence_of :user
                validates_presence_of :credit_card
                validates_presence_of :credit_card_name
                validates_length_of :credit_card, :within => 16..16
                validates_format_of :credit_card, :with => /^d*$/
                validates_length_of :credit_card_name, :within => 3..70

                  def total
                    hotel.price * nights
                  end

                  def nights
                    ((checkout_date - checkin_date) / 1.day).round
                  end

                def to_s
                  "Booking(#{user},#{hotel})"
                end
              end
Friday, August 7, 2009
class CreateBookings < ActiveRecord::Migration
                           def self.up
                             create_table :bookings do |t|
                               t.references :user
                               t.references :hotel
                               t.datetime :checkin
                               t.datetime :checkout
                               t.string :credit_card
                               t.string :credit_card_name
                               t.integer :credit_card_expiry_month
                               t.integer :credit_card_expiry_year
                               t.boolean :smoking
                               t.integer :beds

                               t.timestamps
                             end
                           end

                           def self.down
                             drop_table :bookings
                           end
                         end

Friday, August 7, 2009
class CreateBookings < ActiveRecord::Migration
                           def self.up
                             create_table :bookings do |t|
                               t.references :user
                               t.references :hotel
                               t.datetime :checkin
                               t.datetime :checkout
                               t.string :credit_card
                               t.string :credit_card_name
                               t.integer :credit_card_expiry_month
                               t.integer :credit_card_expiry_year
                               t.boolean :smoking
                               t.integer :beds

                               t.timestamps
                             end
                           end

                           def self.down
                             drop_table :bookings
                           end
                         end

Friday, August 7, 2009
class CreateBookings < ActiveRecord::Migration
                           def self.up
                             create_table :bookings do |t|
                               t.references :user
                               t.references :hotel
                               t.datetime :checkin
                               t.datetime :checkout
                               t.string :credit_card
                               t.string :credit_card_name
                               t.integer :credit_card_expiry_month
                               t.integer :credit_card_expiry_year
                               t.boolean :smoking
                               t.integer :beds

                               t.timestamps
                             end
                           end

                           def self.down
                             drop_table :bookings
                           end
                         end

Friday, August 7, 2009
190
                         vs
                         40

Friday, August 7, 2009
“Eles servem mais de 23 milhões de visitantes/mês. A conversão resultou em
               20 mil linhas de Ruby em vez de 125 mil linhas de Java e, mais importante,
                  facilitou a dificuldade que tinham em manutenção. Eles também
             finalizaram a reescrita do sistema em apenas 3 meses com 4 desenvolvedores.
             Uma vez completo e otimizado, o site deles agora é mais rápido que antes.”




                         http://www.railsonwave.com/railsonwave/2008/6/4/yellowpages-com-migrates-to-rails




Friday, August 7, 2009
“Eles servem mais de 23 milhões de visitantes/mês. A conversão resultou em
               20 mil linhas de Ruby em vez de 125 mil linhas de Java e, mais importante,
                  facilitou a dificuldade que tinham em manutenção. Eles também
             finalizaram a reescrita do sistema em apenas 3 meses com 4 desenvolvedores.
             Uma vez completo e otimizado, o site deles agora é mais rápido que antes.”




                         http://www.railsonwave.com/railsonwave/2008/6/4/yellowpages-com-migrates-to-rails




Friday, August 7, 2009
“Eles servem mais de 23 milhões de visitantes/mês. A conversão resultou em
               20 mil linhas de Ruby em vez de 125 mil linhas de Java e, mais importante,
                  facilitou a dificuldade que tinham em manutenção. Eles também
             finalizaram a reescrita do sistema em apenas 3 meses com 4 desenvolvedores.
             Uma vez completo e otimizado, o site deles agora é mais rápido que antes.”




                         http://www.railsonwave.com/railsonwave/2008/6/4/yellowpages-com-migrates-to-rails




Friday, August 7, 2009
“Eles servem mais de 23 milhões de visitantes/mês. A conversão resultou em
               20 mil linhas de Ruby em vez de 125 mil linhas de Java e, mais importante,
                  facilitou a dificuldade que tinham em manutenção. Eles também
             finalizaram a reescrita do sistema em apenas 3 meses com 4 desenvolvedores.
             Uma vez completo e otimizado, o site deles agora é mais rápido que antes.”




                         http://www.railsonwave.com/railsonwave/2008/6/4/yellowpages-com-migrates-to-rails




Friday, August 7, 2009
Friday, August 7, 2009
11 mil
                         classes!

                         46 só de
                         coleções!


Friday, August 7, 2009
• Classes:
                         • Modules:       • Array
                          • Enumerable    • Hash
                          • Comparable    • Set
                                          • Sorted Set

Friday, August 7, 2009
1.400 Classes:
                                      •
                                 classesArray
                         • Modules:     •
                          • Enumerable    • Hash
                          • Comparable 6 de Set
                                    só    •
                                          • Sorted
                                  coleções! Set


Friday, August 7, 2009
Mitos?



Friday, August 7, 2009
Friday, August 7, 2009
Mais Produtivo




                           “Melhor”




                          Anti-legado


Friday, August 7, 2009
Mais Produtivo




                           “Melhor”




                          Anti-legado


Friday, August 7, 2009
Mais Produtivo




                           “Melhor”




                          Anti-legado


Friday, August 7, 2009
Agilidade



Friday, August 7, 2009
Friday, August 7, 2009
Robert C. Martin


Friday, August 7, 2009
“Uncle Bob”

Friday, August 7, 2009
Código Limpo



Friday, August 7, 2009
Friday, August 7, 2009
Test Driven
                         Development


Friday, August 7, 2009
Friday, August 7, 2009
Ferramentas
                            Ágeis


Friday, August 7, 2009
Gerenciamento



Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Repositórios



Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Integração
                          Contínua


Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Deployment



Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Monitoramento



Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Comunidade



Friday, August 7, 2009
peepcode.com




                                        Geoffrey
Friday, August 7, 2009
railsenvy.com




                                         Jason e Gregg
Friday, August 7, 2009
railscasts.com




                                          Ryan Bates
Friday, August 7, 2009
guias.rubyonrails.pro.br




                                               Pratik Naik
Friday, August 7, 2009
rubylearning.org




                                            Satish Talim
Friday, August 7, 2009
rubyinside.com.br




                                             Peter Cooper
Friday, August 7, 2009
why.nomedojogo.com




                                              _why
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Friday, August 7, 2009
Obrigado!
                          akitaonrails.com




Friday, August 7, 2009

Contenu connexe

En vedette

Investor Day 2009 - Deputy CEO presentation
Investor Day 2009 - Deputy CEO presentationInvestor Day 2009 - Deputy CEO presentation
Investor Day 2009 - Deputy CEO presentationAgeas
 
Aula separados para o senhor
Aula separados para o senhorAula separados para o senhor
Aula separados para o senhorMárcio Pereira
 
O que devo comer? - Priscila Poo
O que devo comer? - Priscila PooO que devo comer? - Priscila Poo
O que devo comer? - Priscila PooOncoguia
 
Proman Higiene ¿Por que?
Proman Higiene ¿Por que?Proman Higiene ¿Por que?
Proman Higiene ¿Por que?inpresionante
 
Via credi info01(29062010)
Via credi info01(29062010)Via credi info01(29062010)
Via credi info01(29062010)Jorge Purgly
 
Venezuela vinheta grupo 5
Venezuela vinheta grupo 5Venezuela vinheta grupo 5
Venezuela vinheta grupo 5blog_setimaf
 
GERÊNCIA E COMPETÊNCIAS GERAIS DO ENFERMEIRO
GERÊNCIA E COMPETÊNCIAS GERAIS DO ENFERMEIROGERÊNCIA E COMPETÊNCIAS GERAIS DO ENFERMEIRO
GERÊNCIA E COMPETÊNCIAS GERAIS DO ENFERMEIROCarolina Franco
 
Apresentação ritmo f2x
Apresentação ritmo f2xApresentação ritmo f2x
Apresentação ritmo f2xCAA
 
A Jogada Do Mané Sr Consultoria
A Jogada Do Mané   Sr ConsultoriaA Jogada Do Mané   Sr Consultoria
A Jogada Do Mané Sr ConsultoriaBrazil
 
Aula V - segurança juridica e processo
Aula V -  segurança juridica e processoAula V -  segurança juridica e processo
Aula V - segurança juridica e processoHeitor Carvalho
 
Apres Institucional R&amp;B2008 2009 Ing
Apres Institucional R&amp;B2008 2009 IngApres Institucional R&amp;B2008 2009 Ing
Apres Institucional R&amp;B2008 2009 Ingademarc
 

En vedette (20)

Investor Day 2009 - Deputy CEO presentation
Investor Day 2009 - Deputy CEO presentationInvestor Day 2009 - Deputy CEO presentation
Investor Day 2009 - Deputy CEO presentation
 
Aula separados para o senhor
Aula separados para o senhorAula separados para o senhor
Aula separados para o senhor
 
Oxente BDD
Oxente BDDOxente BDD
Oxente BDD
 
O que devo comer? - Priscila Poo
O que devo comer? - Priscila PooO que devo comer? - Priscila Poo
O que devo comer? - Priscila Poo
 
Direito
DireitoDireito
Direito
 
Proman Higiene ¿Por que?
Proman Higiene ¿Por que?Proman Higiene ¿Por que?
Proman Higiene ¿Por que?
 
Candidatos São Paulo
Candidatos São PauloCandidatos São Paulo
Candidatos São Paulo
 
O Fator VDM (promo)
O Fator VDM (promo)O Fator VDM (promo)
O Fator VDM (promo)
 
Via credi info01(29062010)
Via credi info01(29062010)Via credi info01(29062010)
Via credi info01(29062010)
 
Gazeta
GazetaGazeta
Gazeta
 
Venezuela vinheta grupo 5
Venezuela vinheta grupo 5Venezuela vinheta grupo 5
Venezuela vinheta grupo 5
 
Sondaterra sonda caladora
Sondaterra   sonda caladoraSondaterra   sonda caladora
Sondaterra sonda caladora
 
Novos Planos Unimed
Novos Planos UnimedNovos Planos Unimed
Novos Planos Unimed
 
GERÊNCIA E COMPETÊNCIAS GERAIS DO ENFERMEIRO
GERÊNCIA E COMPETÊNCIAS GERAIS DO ENFERMEIROGERÊNCIA E COMPETÊNCIAS GERAIS DO ENFERMEIRO
GERÊNCIA E COMPETÊNCIAS GERAIS DO ENFERMEIRO
 
Apresentação ritmo f2x
Apresentação ritmo f2xApresentação ritmo f2x
Apresentação ritmo f2x
 
Chasque 59
Chasque 59Chasque 59
Chasque 59
 
A Jogada Do Mané Sr Consultoria
A Jogada Do Mané   Sr ConsultoriaA Jogada Do Mané   Sr Consultoria
A Jogada Do Mané Sr Consultoria
 
Pedra Alta Campinas
Pedra Alta CampinasPedra Alta Campinas
Pedra Alta Campinas
 
Aula V - segurança juridica e processo
Aula V -  segurança juridica e processoAula V -  segurança juridica e processo
Aula V - segurança juridica e processo
 
Apres Institucional R&amp;B2008 2009 Ing
Apres Institucional R&amp;B2008 2009 IngApres Institucional R&amp;B2008 2009 Ing
Apres Institucional R&amp;B2008 2009 Ing
 

Similaire à Oxente on Rails 2009

DjangoCon 2009 Keynote
DjangoCon 2009 KeynoteDjangoCon 2009 Keynote
DjangoCon 2009 KeynoteTed Leung
 
2009, o ano do Ruby on Rails no Brasil - CaelumDay 2009
2009, o ano do Ruby on Rails no Brasil - CaelumDay 20092009, o ano do Ruby on Rails no Brasil - CaelumDay 2009
2009, o ano do Ruby on Rails no Brasil - CaelumDay 2009Caue Guerra
 
Rhouse - Home automation is ruby ?
Rhouse - Home automation is ruby ?Rhouse - Home automation is ruby ?
Rhouse - Home automation is ruby ?Fernand Galiana
 
MacRuby - When objective-c and Ruby meet
MacRuby - When objective-c and Ruby meetMacRuby - When objective-c and Ruby meet
MacRuby - When objective-c and Ruby meetMatt Aimonetti
 
Software livre e padrões abertos no desenvolvimento Web
Software livre e padrões abertos no desenvolvimento WebSoftware livre e padrões abertos no desenvolvimento Web
Software livre e padrões abertos no desenvolvimento WebFelipe Ribeiro
 
Accelerating Ruby with LLVM
Accelerating Ruby with LLVMAccelerating Ruby with LLVM
Accelerating Ruby with LLVMevanphx
 
Frozen Rails Slides
Frozen Rails SlidesFrozen Rails Slides
Frozen Rails Slidescarllerche
 
5 Fixes for Fall
5 Fixes for Fall5 Fixes for Fall
5 Fixes for FallTargetX
 
The Twitter API: A Presentation to Adobe
The Twitter API: A Presentation to AdobeThe Twitter API: A Presentation to Adobe
The Twitter API: A Presentation to AdobeAlex Payne
 
Become Master of Your Own Universe - DIBI 2013
Become Master of Your Own Universe - DIBI 2013Become Master of Your Own Universe - DIBI 2013
Become Master of Your Own Universe - DIBI 2013Phil Sturgeon
 
Scaling PHP to 40 Million Uniques
Scaling PHP to 40 Million UniquesScaling PHP to 40 Million Uniques
Scaling PHP to 40 Million UniquesJonathan Klein
 
jQuery Mobile Deep Dive
jQuery Mobile Deep DivejQuery Mobile Deep Dive
jQuery Mobile Deep DiveTroy Miles
 
Node Tools For Your Grails Toolbox - Gr8Conf 2013
Node Tools For Your Grails Toolbox - Gr8Conf 2013Node Tools For Your Grails Toolbox - Gr8Conf 2013
Node Tools For Your Grails Toolbox - Gr8Conf 2013zanthrash
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013Charles Nutter
 
JSDay 2013 - Practical Responsive Web Design
JSDay 2013 - Practical Responsive Web DesignJSDay 2013 - Practical Responsive Web Design
JSDay 2013 - Practical Responsive Web DesignJonathan Klein
 
Encontro de TI - Arteccom
Encontro de TI - ArteccomEncontro de TI - Arteccom
Encontro de TI - ArteccomFabio Akita
 
Cooking an Omelette with Chef
Cooking an Omelette with ChefCooking an Omelette with Chef
Cooking an Omelette with Chefctaintor
 
Termtter 2009-03-14
Termtter 2009-03-14Termtter 2009-03-14
Termtter 2009-03-14jugyo kohno
 

Similaire à Oxente on Rails 2009 (20)

Enecomp 2009
Enecomp 2009Enecomp 2009
Enecomp 2009
 
DjangoCon 2009 Keynote
DjangoCon 2009 KeynoteDjangoCon 2009 Keynote
DjangoCon 2009 Keynote
 
2009, o ano do Ruby on Rails no Brasil - CaelumDay 2009
2009, o ano do Ruby on Rails no Brasil - CaelumDay 20092009, o ano do Ruby on Rails no Brasil - CaelumDay 2009
2009, o ano do Ruby on Rails no Brasil - CaelumDay 2009
 
Rhouse - Home automation is ruby ?
Rhouse - Home automation is ruby ?Rhouse - Home automation is ruby ?
Rhouse - Home automation is ruby ?
 
MacRuby - When objective-c and Ruby meet
MacRuby - When objective-c and Ruby meetMacRuby - When objective-c and Ruby meet
MacRuby - When objective-c and Ruby meet
 
Software livre e padrões abertos no desenvolvimento Web
Software livre e padrões abertos no desenvolvimento WebSoftware livre e padrões abertos no desenvolvimento Web
Software livre e padrões abertos no desenvolvimento Web
 
Accelerating Ruby with LLVM
Accelerating Ruby with LLVMAccelerating Ruby with LLVM
Accelerating Ruby with LLVM
 
Frozen Rails Slides
Frozen Rails SlidesFrozen Rails Slides
Frozen Rails Slides
 
5 Fixes for Fall
5 Fixes for Fall5 Fixes for Fall
5 Fixes for Fall
 
The Twitter API: A Presentation to Adobe
The Twitter API: A Presentation to AdobeThe Twitter API: A Presentation to Adobe
The Twitter API: A Presentation to Adobe
 
Become Master of Your Own Universe - DIBI 2013
Become Master of Your Own Universe - DIBI 2013Become Master of Your Own Universe - DIBI 2013
Become Master of Your Own Universe - DIBI 2013
 
Front end-performance
Front end-performanceFront end-performance
Front end-performance
 
Scaling PHP to 40 Million Uniques
Scaling PHP to 40 Million UniquesScaling PHP to 40 Million Uniques
Scaling PHP to 40 Million Uniques
 
jQuery Mobile Deep Dive
jQuery Mobile Deep DivejQuery Mobile Deep Dive
jQuery Mobile Deep Dive
 
Node Tools For Your Grails Toolbox - Gr8Conf 2013
Node Tools For Your Grails Toolbox - Gr8Conf 2013Node Tools For Your Grails Toolbox - Gr8Conf 2013
Node Tools For Your Grails Toolbox - Gr8Conf 2013
 
The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013The Future of JRuby - Baruco 2013
The Future of JRuby - Baruco 2013
 
JSDay 2013 - Practical Responsive Web Design
JSDay 2013 - Practical Responsive Web DesignJSDay 2013 - Practical Responsive Web Design
JSDay 2013 - Practical Responsive Web Design
 
Encontro de TI - Arteccom
Encontro de TI - ArteccomEncontro de TI - Arteccom
Encontro de TI - Arteccom
 
Cooking an Omelette with Chef
Cooking an Omelette with ChefCooking an Omelette with Chef
Cooking an Omelette with Chef
 
Termtter 2009-03-14
Termtter 2009-03-14Termtter 2009-03-14
Termtter 2009-03-14
 

Plus de Fabio Akita

Devconf 2019 - São Carlos
Devconf 2019 - São CarlosDevconf 2019 - São Carlos
Devconf 2019 - São CarlosFabio Akita
 
Meetup Nerdzão - English Talk about Languages
Meetup Nerdzão  - English Talk about LanguagesMeetup Nerdzão  - English Talk about Languages
Meetup Nerdzão - English Talk about LanguagesFabio Akita
 
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018Fabio Akita
 
Desmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SPDesmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SPFabio Akita
 
Desmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter GoianiaDesmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter GoianiaFabio Akita
 
Blockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7MastersBlockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7MastersFabio Akita
 
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
Elixir  -Tolerância a Falhas para Adultos - GDG CampinasElixir  -Tolerância a Falhas para Adultos - GDG Campinas
Elixir -Tolerância a Falhas para Adultos - GDG CampinasFabio Akita
 
Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017Fabio Akita
 
30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to Ruby30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to RubyFabio Akita
 
Uma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TIUma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TIFabio Akita
 
THE CONF - Opening Keynote
THE CONF - Opening KeynoteTHE CONF - Opening Keynote
THE CONF - Opening KeynoteFabio Akita
 
A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017Fabio Akita
 
Desmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - APDesmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - APFabio Akita
 
A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017Fabio Akita
 
A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017Fabio Akita
 
A Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech DayA Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech DayFabio Akita
 
A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016Fabio Akita
 
Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016Fabio Akita
 
Conexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização PrematuraConexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização PrematuraFabio Akita
 
The Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All EvilThe Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All EvilFabio Akita
 

Plus de Fabio Akita (20)

Devconf 2019 - São Carlos
Devconf 2019 - São CarlosDevconf 2019 - São Carlos
Devconf 2019 - São Carlos
 
Meetup Nerdzão - English Talk about Languages
Meetup Nerdzão  - English Talk about LanguagesMeetup Nerdzão  - English Talk about Languages
Meetup Nerdzão - English Talk about Languages
 
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
 
Desmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SPDesmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SP
 
Desmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter GoianiaDesmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter Goiania
 
Blockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7MastersBlockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7Masters
 
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
Elixir  -Tolerância a Falhas para Adultos - GDG CampinasElixir  -Tolerância a Falhas para Adultos - GDG Campinas
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
 
Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017
 
30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to Ruby30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to Ruby
 
Uma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TIUma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TI
 
THE CONF - Opening Keynote
THE CONF - Opening KeynoteTHE CONF - Opening Keynote
THE CONF - Opening Keynote
 
A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017
 
Desmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - APDesmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - AP
 
A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017
 
A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017
 
A Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech DayA Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech Day
 
A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016
 
Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016
 
Conexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização PrematuraConexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização Prematura
 
The Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All EvilThe Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All Evil
 

Dernier

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 

Dernier (20)

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 

Oxente on Rails 2009

  • 1. Ruby on Rails Friday, August 7, 2009
  • 2. AkitaOnRails.com slideshare.net/akitaonrails Friday, August 7, 2009
  • 5. 13 e 14 Outubro 2009 Friday, August 7, 2009
  • 7. ~140 slides ~45 min Friday, August 7, 2009
  • 8. www.slideshare.net/akitaonrails fabio.akita@locaweb.com.br Friday, August 7, 2009
  • 12. Ruby on Rails 2.3 Ruby 1.8 Novo Ruby 1.9 Friday, August 7, 2009
  • 13. Ruby on Rails 2.3 Ruby 1.8 Novo Ruby 1.9 Friday, August 7, 2009
  • 14. Ruby on Rails 2.3 Ruby 1.8 Novo Ruby 1.9 Friday, August 7, 2009
  • 15. “Matz” 1993 Friday, August 7, 2009
  • 17. “Prag Dave” 2001 Friday, August 7, 2009
  • 19. “DHH” 2004 Friday, August 7, 2009
  • 22. Charles Nutter 2006 Friday, August 7, 2009
  • 27. “Tornar as coisas simples fáceis e as coisas complexas possíveis” Filosofia Ruby Friday, August 7, 2009
  • 32. O que dizem por aí ... Friday, August 7, 2009
  • 34. Rails não Escala Friday, August 7, 2009
  • 35. Ruby é Lento Friday, August 7, 2009
  • 49. Rails não Escala Friday, August 7, 2009
  • 51. Blaine Cook http://www.akitaonrails.com/2008/6/17/chatting-with-blaine-cook-twitter Friday, August 7, 2009
  • 52. Para colocar as coisas em perspectiva, o Friendster foi escrito em Java e eles mudaram para PHP. MySpace foi escrito em ColdFusion e eles mudaram para ASP.NET. Blaine Cook http://www.akitaonrails.com/2008/6/17/chatting-with-blaine-cook-twitter Friday, August 7, 2009
  • 53. Para colocar as coisas em perspectiva, o Friendster foi escrito em Java e eles mudaram para PHP. MySpace foi escrito em ColdFusion e eles mudaram para ASP.NET. Quando as pessoas caem em problemas de escalabilidade, normalmente acham que a linguagem é o problema, mas eu acho que isso raramente é a realidade. Blaine Cook http://www.akitaonrails.com/2008/6/17/chatting-with-blaine-cook-twitter Friday, August 7, 2009
  • 54. “O The New York Times usou Ruby on Rails para agregar, analizar e mostrar os resultados das eleições em quase tempo real em um de seus sites mais acessados de todos os tempos.” http://www.computerworld.com.au/article/268003/ruby_rails_rolls_into_enterprise?fp=16&fpid=1 Friday, August 7, 2009
  • 55. “O The New York Times usou Ruby on Rails para agregar, analizar e mostrar os resultados das eleições em quase tempo real em um de seus sites mais acessados de todos os tempos.” http://www.computerworld.com.au/article/268003/ruby_rails_rolls_into_enterprise?fp=16&fpid=1 Friday, August 7, 2009
  • 56. Ruby é Lento Friday, August 7, 2009
  • 57. x mais lento que C++ Friday, August 7, 2009
  • 58. x mais lento que C++ 0 50 100 Python 2 150 Ruby 1.9 200 Perl JRuby Python 3 PHP Ruby 1.8.6 Friday, August 7, 2009
  • 59. Homepage: 331 ms Friday, August 7, 2009
  • 60. Homepage: 331 ms Total: 5.45 s Friday, August 7, 2009
  • 62. Performance != Escalabilidade Friday, August 7, 2009
  • 63. Ruby on Rails Friday, August 7, 2009
  • 65. Código que gera Código Convention over Configuration Don’t Repeat Yourself Extreme Programming Friday, August 7, 2009
  • 66. Código que gera Código Convention over Configuration Don’t Repeat Yourself Extreme Programming Friday, August 7, 2009
  • 67. Código que gera Código Convention over Configuration Don’t Repeat Yourself Extreme Programming Friday, August 7, 2009
  • 68. Código que gera Código Convention over Configuration Don’t Repeat Yourself Extreme Programming Friday, August 7, 2009
  • 83. Model class Product < ActiveRecord::Base after_create :set_initial_inventory has_many :variants, :dependent => :destroy has_many :images, :as => :viewable, :order => :position, :dependent => :destroy has_many :properties, :through => :product_properties belongs_to :tax_category validates_presence_of :name validates_presence_of :master_price validates_presence_of :description make_permalink :with => :name, :field => :permalink end Friday, August 7, 2009
  • 84. Model class Product < ActiveRecord::Base after_create :set_initial_inventory has_many :variants, :dependent => :destroy has_many :images, :as => :viewable, :order => :position, :dependent => :destroy has_many :properties, :through => :product_properties belongs_to :tax_category validates_presence_of :name validates_presence_of :master_price validates_presence_of :description make_permalink :with => :name, :field => :permalink end Friday, August 7, 2009
  • 85. Model class Product < ActiveRecord::Base after_create :set_initial_inventory has_many :variants, :dependent => :destroy has_many :images, :as => :viewable, :order => :position, :dependent => :destroy has_many :properties, :through => :product_properties belongs_to :tax_category validates_presence_of :name validates_presence_of :master_price validates_presence_of :description make_permalink :with => :name, :field => :permalink end Friday, August 7, 2009
  • 86. Model class Product < ActiveRecord::Base after_create :set_initial_inventory has_many :variants, :dependent => :destroy has_many :images, :as => :viewable, :order => :position, :dependent => :destroy has_many :properties, :through => :product_properties belongs_to :tax_category validates_presence_of :name validates_presence_of :master_price validates_presence_of :description make_permalink :with => :name, :field => :permalink end Friday, August 7, 2009
  • 87. Model class Product < ActiveRecord::Base after_create :set_initial_inventory has_many :variants, :dependent => :destroy has_many :images, :as => :viewable, :order => :position, :dependent => :destroy has_many :properties, :through => :product_properties belongs_to :tax_category validates_presence_of :name validates_presence_of :master_price validates_presence_of :description make_permalink :with => :name, :field => :permalink end Friday, August 7, 2009
  • 88. Model class Product < ActiveRecord::Base after_create :set_initial_inventory has_many :variants, :dependent => :destroy has_many :images, :as => :viewable, :order => :position, :dependent => :destroy has_many :properties, :through => :product_properties belongs_to :tax_category validates_presence_of :name validates_presence_of :master_price validates_presence_of :description make_permalink :with => :name, :field => :permalink end Friday, August 7, 2009
  • 89. Model class Product < ActiveRecord::Base after_create :set_initial_inventory has_many :variants, :dependent => :destroy has_many :images, :as => :viewable, :order => :position, :dependent => :destroy has_many :properties, :through => :product_properties belongs_to :tax_category validates_presence_of :name validates_presence_of :master_price validates_presence_of :description make_permalink :with => :name, :field => :permalink end Friday, August 7, 2009
  • 90. Model class Product < ActiveRecord::Base after_create :set_initial_inventory has_many :variants, :dependent => :destroy has_many :images, :as => :viewable, :order => :position, :dependent => :destroy has_many :properties, :through => :product_properties belongs_to :tax_category validates_presence_of :name validates_presence_of :master_price validates_presence_of :description make_permalink :with => :name, :field => :permalink end Friday, August 7, 2009
  • 91. Model class Product < ActiveRecord::Base after_create :set_initial_inventory has_many :variants, :dependent => :destroy has_many :images, :as => :viewable, :order => :position, :dependent => :destroy has_many :properties, :through => :product_properties Product.find(1) belongs_to :tax_category validates_presence_of :name validates_presence_of :master_price validates_presence_of :description make_permalink :with => :name, :field => :permalink end Friday, August 7, 2009
  • 92. Views ERB <div id="product-listing"> <%= breadcrumbs(@taxon) %> <br/> <%= render :partial => "shared/products.html.erb", :locals => {:products => @products, :taxon => @taxon } %> </div> <% content_for :sidebar do %> <td id="shop-by-col" valign="top"> <%= render :partial => "shared/taxonomies" %> </td> <% end %> <%= render :partial => 'shared/paginate', :locals => {:collection => @products, :options => {}} unless @products.empty? %> Friday, August 7, 2009
  • 93. Views ERB <div id="product-listing"> <%= breadcrumbs(@taxon) %> <br/> <%= render :partial => "shared/products.html.erb", :locals => {:products => @products, :taxon => @taxon } %> </div> <% content_for :sidebar do %> <td id="shop-by-col" valign="top"> <%= render :partial => "shared/taxonomies" %> </td> <% end %> <%= render :partial => 'shared/paginate', :locals => {:collection => @products, :options => {}} unless @products.empty? %> Friday, August 7, 2009
  • 94. Views ERB <div id="product-listing"> <%= breadcrumbs(@taxon) %> <br/> <%= render :partial => "shared/products.html.erb", :locals => {:products => @products, :taxon => @taxon } %> </div> <% content_for :sidebar do %> <td id="shop-by-col" valign="top"> <%= render :partial => "shared/taxonomies" %> </td> <% end %> <%= render :partial => 'shared/paginate', :locals => {:collection => @products, :options => {}} unless @products.empty? %> Friday, August 7, 2009
  • 95. Rotas RESTFul ActionController::Routing::Routes.draw do |map| map.resources :products map.resources :addresses map.resources :orders, :has_many => [:line_items] map.namespace :admin do |admin| admin.resources :users admin.resources :products end end Friday, August 7, 2009
  • 96. Rotas RESTFul ActionController::Routing::Routes.draw do |map| map.resources :products map.resources :addresses map.resources :orders, :has_many => [:line_items] map.namespace :admin do |admin| admin.resources :users admin.resources :products end end Friday, August 7, 2009
  • 97. Rotas RESTFul ActionController::Routing::Routes.draw do |map| map.resources :products map.resources :addresses map.resources :orders, :has_many => [:line_items] map.namespace :admin do |admin| admin.resources :users admin.resources :products end end Friday, August 7, 2009
  • 98. Rotas RESTFul ActionController::Routing::Routes.draw do |map| map.resources :products map.resources :addresses map.resources :orders, :has_many => [:line_items] map.namespace :admin do |admin| admin.resources :users admin.resources :products end end Friday, August 7, 2009
  • 99. Rotas RESTFul GET /products/new ActionController::Routing::Routes.draw do |map| GET /products POST /products map.resources :products map.resources :addresses map.resourcesGET /products/1 => [:line_items] :orders, :has_many map.namespaceGET /products/1/edit :admin do |admin| PUT /products/1 admin.resources :users admin.resources :products end DESTROY /products/1 end Friday, August 7, 2009
  • 100. Controller class UsersController < Spree::BaseController resource_controller before_filter :initialize_extension_partials actions :all, :except => [:index, :destroy] show.before do @orders = Order.checkout_completed(true) .find_all_by_user_id(current_user.id) end create.after { self.current_user = @user } create.response do |wants| wants.html { redirect_back_or_default(products_path) } end end Friday, August 7, 2009
  • 101. Controller class UsersController < Spree::BaseController resource_controller before_filter :initialize_extension_partials actions :all, :except => [:index, :destroy] show.before do @orders = Order.checkout_completed(true) .find_all_by_user_id(current_user.id) end create.after { self.current_user = @user } create.response do |wants| wants.html { redirect_back_or_default(products_path) } end end Friday, August 7, 2009
  • 102. Controller class UsersController < Spree::BaseController resource_controller before_filter :initialize_extension_partials actions :all, :except => [:index, :destroy] show.before do @orders = Order.checkout_completed(true) .find_all_by_user_id(current_user.id) end create.after { self.current_user = @user } create.response do |wants| wants.html { redirect_back_or_default(products_path) } end end Friday, August 7, 2009
  • 103. Controller class UsersController < Spree::BaseController resource_controller before_filter :initialize_extension_partials actions :all, :except => [:index, :destroy] show.before do @orders = Order.checkout_completed(true) .find_all_by_user_id(current_user.id) end create.after { self.current_user = @user } create.response do |wants| wants.html { redirect_back_or_default(products_path) } end end Friday, August 7, 2009
  • 104. Controller class UsersController < Spree::BaseController resource_controller before_filter :initialize_extension_partials actions :all, :except => [:index, :destroy] show.before do @orders = Order.checkout_completed(true) /users/1 .find_all_by_user_id(current_user.id) end create.after { self.current_user = @user } create.response do |wants| wants.html { redirect_back_or_default(products_path) } end end Friday, August 7, 2009
  • 105. Migrations class RenameAppConfiguration < ActiveRecord::Migration def self.up rename_table :app_configurations, :configurations change_table :configurations do |t| t.string :type end end def self.down change_table :configurations do |t| t.remove :type end rename_table :configurations, :app_configurations end end Friday, August 7, 2009
  • 106. Migrations class RenameAppConfiguration < ActiveRecord::Migration def self.up rename_table :app_configurations, :configurations change_table :configurations do |t| t.string :type end end def self.down change_table :configurations do |t| t.remove :type end rename_table :configurations, :app_configurations end end Friday, August 7, 2009
  • 107. Migrations class RenameAppConfiguration < ActiveRecord::Migration def self.up rename_table :app_configurations, :configurations change_table :configurations do |t| t.string :type end end def self.down change_table :configurations do |t| t.remove :type end rename_table :configurations, :app_configurations end end Friday, August 7, 2009
  • 108. Migrations class RenameAppConfiguration < ActiveRecord::Migration def self.up rename_table :app_configurations, :configurations change_table :configurations do |t| t.string :type end end def self.down change_table :configurations do |t| t.remove :type end rename_table :configurations, :app_configurations end end Friday, August 7, 2009
  • 109. Migrations class RenameAppConfiguration < ActiveRecord::Migration def self.up rename_table :app_configurations, :configurations change_table :configurations do |t| t.string :type end end rake db:migrate def self.down change_table :configurations do |t| t.remove :type end rename_table :configurations, :app_configurations end end Friday, August 7, 2009
  • 112. describe BankAccount do before :each do @bank_account = BankAccount.new :balance => 250 end it "should not be valid" do @bank_account.should be_valid end it "should transfer funds successfully" do @bank_account.should_receive(:transfer) .with_args(:amount => 100) .and_return(true) @bank_account.execute_transaction(:amount => 100) @bank_account.balance.should == 150 end end Friday, August 7, 2009
  • 113. describe BankAccount do before :each do @bank_account = BankAccount.new :balance => 250 end it "should not be valid" do @bank_account.should be_valid end it "should transfer funds successfully" do @bank_account.should_receive(:transfer) .with_args(:amount => 100) .and_return(true) @bank_account.execute_transaction(:amount => 100) @bank_account.balance.should == 150 end end Friday, August 7, 2009
  • 114. describe BankAccount do before :each do @bank_account = BankAccount.new :balance => 250 end it "should not be valid" do @bank_account.should be_valid end it "should transfer funds successfully" do @bank_account.should_receive(:transfer) .with_args(:amount => 100) .and_return(true) @bank_account.execute_transaction(:amount => 100) @bank_account.balance.should == 150 end end Friday, August 7, 2009
  • 115. describe BankAccount do before :each do @bank_account = BankAccount.new :balance => 250 end it "should not be valid" do @bank_account.should be_valid end it "should transfer funds successfully" do @bank_account.should_receive(:transfer) .with_args(:amount => 100) .and_return(true) @bank_account.execute_transaction(:amount => 100) @bank_account.balance.should == 150 end end Friday, August 7, 2009
  • 117. Funcionalidade: Adição Para evitar erros bobos Como um péssimo matemático Eu quero saber como somar dois números Cenário: Adicionar dois números Dado que eu digitei 50 na calculadora E que eu digitei 70 na calculadora Quando eu aperto o botão de soma Então o resultado na calculadora deve ser 120 Friday, August 7, 2009
  • 118. Funcionalidade: Adição Para evitar erros bobos Como um péssimo matemático Eu quero saber como somar dois números Cenário: Adicionar dois números Dado que eu digitei 50 na calculadora E que eu digitei 70 na calculadora Quando eu aperto o botão de soma Então o resultado na calculadora deve ser 120 Friday, August 7, 2009
  • 119. Before do @calc = Calculadora.new end Dado /que eu digitei (d+) na calculadora/ do |n| @calc.push n.to_i end Quando 'eu aperto o botão de soma' do @result = @calc.soma end Então /o resultado na calculadora deve ser (d*)/ do |result| @result.should == result.to_i end Friday, August 7, 2009
  • 120. Before do @calc = Calculadora.new end Dado /que eu digitei (d+) na calculadora/ do |n| @calc.push n.to_i end Quando 'eu aperto o botão de soma' do @result = @calc.soma end Então /o resultado na calculadora deve ser (d*)/ do |result| @result.should == result.to_i end Friday, August 7, 2009
  • 121. Before do @calc = Calculadora.new end Dado /que eu digitei (d+) na calculadora/ do |n| @calc.push n.to_i end Quando 'eu aperto o botão de soma' do @result = @calc.soma end Então /o resultado na calculadora deve ser (d*)/ do |result| @result.should == result.to_i end Friday, August 7, 2009
  • 122. Before do @calc = Calculadora.new end Dado /que eu digitei (d+) na calculadora/ do |n| @calc.push n.to_i end Quando 'eu aperto o botão de soma' do @result = @calc.soma end Então /o resultado na calculadora deve ser (d*)/ do |result| @result.should == result.to_i end Friday, August 7, 2009
  • 123. class SignupTest < ActionController::IntegrationTest def test_trial_account_sign_up visit home_path click_link "Sign up" fill_in "Email", :with => "good@example.com" select "Free account" click_button "Register" end end Friday, August 7, 2009
  • 125. rspec rspec.info cucumber cukes.info shoulda thoughtbot.com/projects/shoulda webrat github.com/brynary/webrat integrity integrityapp.com ZenTest zenspider.com Friday, August 7, 2009
  • 126. • plugins de Active Record • plugins de Views • plugins de Localização • CMS • Parsers • Autenticadores/Autorizadores Friday, August 7, 2009
  • 128. @Transient public BigDecimal getTotal() //$Id: Booking.java 5579 2007-06-27 00:06:49Z gavin $ { package org.jboss.seam.example.booking; return hotel.getPrice().multiply( new BigDecimal( getNights() ) ); } import java.io.Serializable; import java.math.BigDecimal; @Transient import java.text.DateFormat; public int getNights() import java.util.Date; { return (int) ( checkoutDate.getTime() - checkinDate.getTime() ) / import javax.persistence.Basic; 1000 / 60 / 60 / 24; import javax.persistence.Entity; } import javax.persistence.GeneratedValue; import javax.persistence.Id; @Id @GeneratedValue import javax.persistence.ManyToOne; public Long getId() import javax.persistence.Temporal; { import javax.persistence.TemporalType; return id; import javax.persistence.Transient; } public void setId(Long id) import org.hibernate.validator.Length; { import org.hibernate.validator.NotNull; this.id = id; import org.hibernate.validator.Pattern; } import org.jboss.seam.annotations.Name; @NotNull @Entity @Basic @Temporal(TemporalType.DATE) @Name("booking") public Date getCheckinDate() public class Booking implements Serializable { { return checkinDate; private Long id; } private User user; public void setCheckinDate(Date datetime) private Hotel hotel; { private Date checkinDate; this.checkinDate = datetime; private Date checkoutDate; } private String creditCard; private String creditCardName; @ManyToOne @NotNull private int creditCardExpiryMonth; public Hotel getHotel() private int creditCardExpiryYear; { private boolean smoking; return hotel; private int beds; } public void setHotel(Hotel hotel) public Booking() {} { this.hotel = hotel; public Booking(Hotel hotel, User user) } { this.hotel = hotel; @ManyToOne @NotNull this.user = user; public User getUser() } { return user; } Friday, August 7, 2009
  • 129. public int getBeds() public void setUser(User user) { { return beds; this.user = user; } } public void setBeds(int beds) @Basic @Temporal(TemporalType.DATE) { @NotNull this.beds = beds; public Date getCheckoutDate() } { @NotNull(message="Credit card name is required") return checkoutDate; @Length(min=3, max=70, message="Credit card name is required") } public String getCreditCardName() public void setCheckoutDate(Date checkoutDate) { { return creditCardName; this.checkoutDate = checkoutDate; } } public void setCreditCardName(String creditCardName) @NotNull(message="Credit card number is required") { @Length(min=16, max=16, message="Credit card number must 16 digits long") this.creditCardName = creditCardName; @Pattern(regex="^d*$", message="Credit card number must be numeric") } public String getCreditCard() { public int getCreditCardExpiryMonth() return creditCard; { } return creditCardExpiryMonth; } public void setCreditCard(String creditCard) { public void setCreditCardExpiryMonth(int creditCardExpiryMonth) this.creditCard = creditCard; { } this.creditCardExpiryMonth = creditCardExpiryMonth; } @Transient public String getDescription() public int getCreditCardExpiryYear() { { DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM); return creditCardExpiryYear; return hotel==null ? null : hotel.getName() + } ", " + df.format( getCheckinDate() ) + " to " + df.format( getCheckoutDate() ); public void setCreditCardExpiryYear(int creditCardExpiryYear) } { this.creditCardExpiryYear = creditCardExpiryYear; public boolean isSmoking() } { return smoking; @Override } public String toString() { public void setSmoking(boolean smoking) return "Booking(" + user + ","+ hotel + ")"; { } this.smoking = smoking; } } Friday, August 7, 2009
  • 130. class Booking < ActiveRecord::Base belongs_to :hotel belongs_to :user validates_presence_of :hotel validates_presence_of :user validates_presence_of :credit_card validates_presence_of :credit_card_name validates_length_of :credit_card, :within => 16..16 validates_format_of :credit_card, :with => /^d*$/ validates_length_of :credit_card_name, :within => 3..70 def total hotel.price * nights end def nights ((checkout_date - checkin_date) / 1.day).round end def to_s "Booking(#{user},#{hotel})" end end Friday, August 7, 2009
  • 131. class Booking < ActiveRecord::Base belongs_to :hotel belongs_to :user validates_presence_of :hotel validates_presence_of :user validates_presence_of :credit_card validates_presence_of :credit_card_name validates_length_of :credit_card, :within => 16..16 validates_format_of :credit_card, :with => /^d*$/ validates_length_of :credit_card_name, :within => 3..70 def total hotel.price * nights end def nights ((checkout_date - checkin_date) / 1.day).round end def to_s "Booking(#{user},#{hotel})" end end Friday, August 7, 2009
  • 132. class CreateBookings < ActiveRecord::Migration def self.up create_table :bookings do |t| t.references :user t.references :hotel t.datetime :checkin t.datetime :checkout t.string :credit_card t.string :credit_card_name t.integer :credit_card_expiry_month t.integer :credit_card_expiry_year t.boolean :smoking t.integer :beds t.timestamps end end def self.down drop_table :bookings end end Friday, August 7, 2009
  • 133. class CreateBookings < ActiveRecord::Migration def self.up create_table :bookings do |t| t.references :user t.references :hotel t.datetime :checkin t.datetime :checkout t.string :credit_card t.string :credit_card_name t.integer :credit_card_expiry_month t.integer :credit_card_expiry_year t.boolean :smoking t.integer :beds t.timestamps end end def self.down drop_table :bookings end end Friday, August 7, 2009
  • 134. class CreateBookings < ActiveRecord::Migration def self.up create_table :bookings do |t| t.references :user t.references :hotel t.datetime :checkin t.datetime :checkout t.string :credit_card t.string :credit_card_name t.integer :credit_card_expiry_month t.integer :credit_card_expiry_year t.boolean :smoking t.integer :beds t.timestamps end end def self.down drop_table :bookings end end Friday, August 7, 2009
  • 135. 190 vs 40 Friday, August 7, 2009
  • 136. “Eles servem mais de 23 milhões de visitantes/mês. A conversão resultou em 20 mil linhas de Ruby em vez de 125 mil linhas de Java e, mais importante, facilitou a dificuldade que tinham em manutenção. Eles também finalizaram a reescrita do sistema em apenas 3 meses com 4 desenvolvedores. Uma vez completo e otimizado, o site deles agora é mais rápido que antes.” http://www.railsonwave.com/railsonwave/2008/6/4/yellowpages-com-migrates-to-rails Friday, August 7, 2009
  • 137. “Eles servem mais de 23 milhões de visitantes/mês. A conversão resultou em 20 mil linhas de Ruby em vez de 125 mil linhas de Java e, mais importante, facilitou a dificuldade que tinham em manutenção. Eles também finalizaram a reescrita do sistema em apenas 3 meses com 4 desenvolvedores. Uma vez completo e otimizado, o site deles agora é mais rápido que antes.” http://www.railsonwave.com/railsonwave/2008/6/4/yellowpages-com-migrates-to-rails Friday, August 7, 2009
  • 138. “Eles servem mais de 23 milhões de visitantes/mês. A conversão resultou em 20 mil linhas de Ruby em vez de 125 mil linhas de Java e, mais importante, facilitou a dificuldade que tinham em manutenção. Eles também finalizaram a reescrita do sistema em apenas 3 meses com 4 desenvolvedores. Uma vez completo e otimizado, o site deles agora é mais rápido que antes.” http://www.railsonwave.com/railsonwave/2008/6/4/yellowpages-com-migrates-to-rails Friday, August 7, 2009
  • 139. “Eles servem mais de 23 milhões de visitantes/mês. A conversão resultou em 20 mil linhas de Ruby em vez de 125 mil linhas de Java e, mais importante, facilitou a dificuldade que tinham em manutenção. Eles também finalizaram a reescrita do sistema em apenas 3 meses com 4 desenvolvedores. Uma vez completo e otimizado, o site deles agora é mais rápido que antes.” http://www.railsonwave.com/railsonwave/2008/6/4/yellowpages-com-migrates-to-rails Friday, August 7, 2009
  • 141. 11 mil classes! 46 só de coleções! Friday, August 7, 2009
  • 142. • Classes: • Modules: • Array • Enumerable • Hash • Comparable • Set • Sorted Set Friday, August 7, 2009
  • 143. 1.400 Classes: • classesArray • Modules: • • Enumerable • Hash • Comparable 6 de Set só • • Sorted coleções! Set Friday, August 7, 2009
  • 146. Mais Produtivo “Melhor” Anti-legado Friday, August 7, 2009
  • 147. Mais Produtivo “Melhor” Anti-legado Friday, August 7, 2009
  • 148. Mais Produtivo “Melhor” Anti-legado Friday, August 7, 2009
  • 151. Robert C. Martin Friday, August 7, 2009
  • 155. Test Driven Development Friday, August 7, 2009
  • 157. Ferramentas Ágeis Friday, August 7, 2009
  • 165. Integração Contínua Friday, August 7, 2009
  • 178. peepcode.com Geoffrey Friday, August 7, 2009
  • 179. railsenvy.com Jason e Gregg Friday, August 7, 2009
  • 180. railscasts.com Ryan Bates Friday, August 7, 2009
  • 181. guias.rubyonrails.pro.br Pratik Naik Friday, August 7, 2009
  • 182. rubylearning.org Satish Talim Friday, August 7, 2009
  • 183. rubyinside.com.br Peter Cooper Friday, August 7, 2009
  • 184. why.nomedojogo.com _why Friday, August 7, 2009
  • 192. Obrigado! akitaonrails.com Friday, August 7, 2009