0
Rails 3


Hugo Baraúna    blog.plataformatec.com   @hugobarauna
Rails 3

   ID                   blog                 twitter

Hugo Baraúna    blog.plataformatec.com   @hugobarauna
Quem sou eu?
      • Hugo     Baraúna

      • 24     anos

      • Engenharia    de Computação na Politécnica da USP

   ...
Hugo Baraúna   blog.plataformatec.com   @hugobarauna
Desevolvemos
aplicações em Rails




 Coaching em                              Consultoria
 Rails e Agile

Hugo Baraúna   ...
Arquitetura
               Rails 3

                       Rails

                ActionDispatch

                 ActiveS...
Arquitetura
                                    Todo o resto são
               Rails 3                  Railties!

      ...
Arquitetura
                                              Todo o resto são
                        Rails 3                ...
Vantagens do Rails 3




Hugo Baraúna         blog.plataformatec.com   @hugobarauna
Vantagens do Rails 3




                    Performance



Hugo Baraúna         blog.plataformatec.com   @hugobarauna
Vantagens do Rails 3



                      Agnóstico


                    Performance



Hugo Baraúna         blog.pla...
Vantagens do Rails 3

                    Modularidade


                      Agnóstico


                    Performance...
Instalação

               guru/code$ gem install tzinfo builder memcache-client rack
               rack-test rack-mount ...
rails command
  Rails 2.3                                   Rails 3
  ruby script/server                          rails se...
blog/config.ru


               require ::File.expand_path('../config/environment',   __FILE__)
               run Blog::Ap...
blog/config.ru


               require ::File.expand_path('../config/environment',   __FILE__)
               run Blog::Ap...
blog/config/application.rb
        require File.expand_path('../boot', __FILE__)
        require 'rails/all'

        Bundl...
blog/config/application.rb
        require File.expand_path('../boot', __FILE__)
        require 'rails/all'

        Bundl...
blog/config/application.rb
        require File.expand_path('../boot', __FILE__)
        require 'rails/all'

        Bundl...
blog/config/application.rb
        require File.expand_path('../boot', __FILE__)
        require 'rails/all'

        Bundl...
blog/config/boot.rb
         require 'rubygems'

         # Set up gems listed in the Gemfile.
         gemfile = File.expa...
blog/config/boot.rb
         require 'rubygems'

         # Set up gems listed in the Gemfile.
         gemfile = File.expa...
Bundler
               Router
               ActionMailer
               ActiveModel
               Responders
           ...
Hugo Baraúna   blog.plataformatec.com   @hugobarauna
Biblioteca para gerenciamento de
           dependências



Hugo Baraúna   blog.plataformatec.com   @hugobarauna
# Gemfile
        source 'http://rubygems.org'

        # Bundle edge Rails instead:
        gem 'rails', :git => 'git://g...
# Gemfile
        source 'http://rubygems.org'

        # Bundle edge Rails instead:
        gem 'rails', :git => 'git://g...
# Gemfile
        source 'http://rubygems.org'

        # Bundle edge Rails instead:
        gem 'rails', :git => 'git://g...
Resolução de dependências




Hugo Baraúna    blog.plataformatec.com   @hugobarauna
Resolução de dependências

               guru/code$ gem dependency actionpack -v="2.3.5"
               Gem actionpack-2....
Resolução de dependências

               guru/code$ gem dependency actionpack -v="2.3.5"
               Gem actionpack-2....
Resolução de dependências
               require "rubygems"
               require "thin"
               gem "actionpack",...
Resolução de dependências
                     require "rubygems"
                     require "thin"
                    ...
Gemfile
               # Gemfile
               gem "thin"
               gem "actionpack", "2.3.5"




Hugo Baraúna       ...
Gemfile
               # Gemfile
               gem "thin"
               gem "actionpack", "2.3.5"



               guru/...
Gemfile
               # Gemfile
               gem "thin"
               gem "actionpack", "2.3.5"



               guru/...
Lock no $LOAD_PATH




Hugo Baraúna         blog.plataformatec.com   @hugobarauna
Esqueci de colocar no config.gem!




Hugo Baraúna   blog.plataformatec.com   @hugobarauna
Esqueci de colocar no config.gem!




Hugo Baraúna   blog.plataformatec.com   @hugobarauna
}
         guru/code$ gem list
         *** LOCAL GEMS ***

         bundler (0.9.25)
         rake (0.8.7, 0.8.5)
       ...
}
         guru/code$ gem list
         *** LOCAL GEMS ***

         bundler (0.9.25)
         rake (0.8.7, 0.8.5)
       ...
}
         guru/code$ gem list
         *** LOCAL GEMS ***

         bundler (0.9.25)
         rake (0.8.7, 0.8.5)
       ...
guru/code$ gem list
               rake (0.8.7, 0.8.5)
               thor (0.13.6)




Hugo Baraúna                   blo...
guru/code$ gem list
               rake (0.8.7, 0.8.5)
               thor (0.13.6)



               # Gemfile
          ...
guru/code$ gem list
               rake (0.8.7, 0.8.5)
               thor (0.13.6)



               # Gemfile
          ...
guru/code$ gem list
               rake (0.8.7, 0.8.5)
               thor (0.13.6)



               # Gemfile
          ...
guru/code$ gem list
               rake (0.8.7, 0.8.5)
               thor (0.13.6)



               # Gemfile
          ...
guru/code$ gem list
               rake (0.8.7, 0.8.5)
               thor (0.13.6)



               # Gemfile
          ...
Hugo Baraúna   blog.plataformatec.com   @hugobarauna
Bundler
               Router
               ActionMailer
               ActiveModel
               Responders
           ...
Router




Hugo Baraúna   blog.plataformatec.com   @hugobarauna
Nova API




Hugo Baraúna   blog.plataformatec.com   @hugobarauna
Rotas root
  Rails 2.3

               map.root :controller => "welcome"




  Rails 3
                  root :to => "welc...
Rotas comum
  Rails 2.3

 map.connect "products/:id", controller=> "catalog", :action => "view"




  Rails 3
            ...
Named routes
  Rails 2.3
       map.purchase "products/:id/purchase", :controller => "catalog",
          :action => "purc...
Resources com member e
                collection
  Rails 2.3

     map.resources :products, :member => { :short => :get,
...
Router and Rack FTW!




Hugo Baraúna         blog.plataformatec.com   @hugobarauna
Rack FTW!




Hugo Baraúna    blog.plataformatec.com   @hugobarauna
Rack FTW!
               match "posts/:echo" => "posts#show"




Hugo Baraúna             blog.plataformatec.com      @hug...
Rack FTW!
                   match "posts/:echo" => "posts#show"
                                                      uma...
Rack FTW!
                   match "posts/:echo" => "posts#show"



           match "posts/:echo" => PostsController.acti...
Rack FTW!
                   match "posts/:echo" => "posts#show"



           match "posts/:echo" => PostsController.acti...
Bundler
               Router
               ActionMailer
               ActiveModel
               Responders
           ...
ActionMailer new API




Hugo Baraúna         blog.plataformatec.com   @hugobarauna
ActionMailer new API
       guru/code$ rails g mailer Notifier signup_notification
           create app/mailers/notifier.rb
...
ActionMailer new API
       guru/code$ rails g mailer Notifier signup_notification
           create app/mailers/notifier.rb
...
ActionMailer new API
               class Notifier < ActionMailer::Base
                 default :from => "system@example....
ActionMailer new API
               class Notifier < ActionMailer::Base
Variáveis        default :from => "system@example....
ActionMailer new API
               class Notifier < ActionMailer::Base
Variáveis        default :from => "system@example....
ActionMailer new API
               class Notifier < ActionMailer::Base
Variáveis        default :from => "system@example....
AbstractController::Base




                                               ActionController::Metal




       ActionMaile...
Bundler
               Router
               ActionMailer
               ActiveModel
               Responders
           ...
ActiveModel




Hugo Baraúna     blog.plataformatec.com   @hugobarauna
ActiveModel




Hugo Baraúna     blog.plataformatec.com   @hugobarauna
ActiveModel
• Google       Summer of Code 2009:




Hugo Baraúna               blog.plataformatec.com   @hugobarauna
ActiveModel
• Google       Summer of Code 2009:

  • Extraira lógica comum entre ActiveRecord e
    ActiveResource




Hug...
ActiveModel
• Google       Summer of Code 2009:

  • Extraira lógica comum entre ActiveRecord e
    ActiveResource

• Hoje...
ActiveModel
• Google       Summer of Code 2009:

  • Extraira lógica comum entre ActiveRecord e
    ActiveResource

• Hoje...
ActiveModel
• Google       Summer of Code 2009:

  • Extraira lógica comum entre ActiveRecord e
    ActiveResource

• Hoje...
ActiveResource::Base +
                    ActiveModel
               module ActiveResource
                 ...
         ...
ActiveRecord::Base +
                   ActiveModel
         Base.class_eval do
             ...
             extend Activ...
Agnosticismo de ORM




Hugo Baraúna         blog.plataformatec.com   @hugobarauna
Agnosticismo de ORM

                      Agnosticismo de ORM


                 ActiveModel               Rails::Railtie...
Agnosticismo de ORM

                      Agnosticismo de ORM


                 ActiveModel                Rails::Railti...
Agnosticismo de ORM

                      Agnosticismo de ORM


                 ActiveModel                Rails::Railti...
ActiveModel::Lint::Tests




Hugo Baraúna          blog.plataformatec.com   @hugobarauna
module ActiveModel
                 module Lint
                   module Tests

                     def test_to_key
    ...
def test_to_param
             assert model.respond_to?(:to_param), "The model should
     respond to to_param"
          ...
ActiveRecord-like
                        Ótimo exemplo de uso do ActiveModel




    http://github.com/plataformatec/mail...
ActiveModel




Hugo Baraúna     blog.plataformatec.com   @hugobarauna
Bundler
               Router
               ActionMailer
               ActiveModel
               Responders
           ...
Responders




Hugo Baraúna    blog.plataformatec.com   @hugobarauna
RAILS 2.3

     def index
       @users = User.all
       respond_to do |format|
         format.html # index.html.erb
   ...
RAILS 2.3

     def index
       @users = User.all
       respond_to do |format|
         format.html # index.html.erb
   ...
RAILS 3.0

               respond_to :html, :xml

               def index
                 @users = User.all
            ...
RAILS 3.0

               respond_to :html, :xml

               def index
                 @users = User.all
            ...
Navigational             API

        GET


        POST



        PUT


      DELETE

Hugo Baraúna   blog.plataformatec....
Navigational               API

        GET


        POST



        PUT


      DELETE

Hugo Baraúna     blog.plataforma...
Navigational             API

        GET


       POST



        PUT


     DELETE

Hugo Baraúna   blog.plataformatec.co...
respond_to :html, :xml

               def index
                 @users = User.all
                 respond_with(@users)
...
Navigational                      API
                                                  render
        GET    render templ...
RAILS 2.3
def create
  @user = User.new(params[:user])
  respond_to do |format|
    if @user.save
      format.html { redi...
RAILS 3.0

   def create
     @user = User.new(params[:user])
     flash[:notice] = 'User was successfully created' if @us...
Navigational                      API
                                                               render
        GET   ...
Navigational                       API
                                                                render
        GET ...
respond_with(@users)

               ActionController::Responder




Hugo Baraúna           blog.plataformatec.com   @hugo...
respond_with(@users)

               ActionController::Responder


                                                       ...
Responders Customizados




Hugo Baraúna    blog.plataformatec.com   @hugobarauna
github.com/plataformatec/responders




Hugo Baraúna    blog.plataformatec.com   @hugobarauna
github.com/plataformatec/responders




Hugo Baraúna    blog.plataformatec.com   @hugobarauna
github.com/plataformatec/responders


FlashResponder: seta o flash baseado na action do
controller e no status do recurso

...
github.com/plataformatec/responders


FlashResponder: seta o flash baseado na action do
controller e no status do recurso

...
CONFIGURANDO O RESPONDERS
        # lib/application_responder.rb
        class ApplicationResponder < ActionController::Re...
CONFIGURANDO O RESPONDERS
        # lib/application_responder.rb
        class ApplicationResponder < ActionController::Re...
SEM O RESPONDERS

   # app/controllers/users_controller.rb
   def create
     @user = User.new(params[:user])
     flash[:...
SEM O RESPONDERS

   # app/controllers/users_controller.rb
   def create
     @user = User.new(params[:user])
     flash[:...
COM O RESPONDERS
           # app/controllers/users_controller.rb
           def create
             @user = User.new(para...
Responders




Hugo Baraúna    blog.plataformatec.com   @hugobarauna
Bundler
               Router
               ActionMailer
               ActiveModel
               Responders
           ...
ARel




Hugo Baraúna   blog.plataformatec.com   @hugobarauna
Lazy loading
        # Rails 2.3
        Job.find(:all, :conditions => {:published => true})


        Faz um query no DB ...
Onde a query roda?
      # app/controllers/jobs_controller.rb
      class JobsController < ApplicationController
        d...
Onde a query roda?
      # app/controllers/jobs_controller.rb
      class JobsController < ApplicationController
        d...
Onde a query roda?
      # app/controllers/jobs_controller.rb
      class JobsController < ApplicationController
        d...
Onde a query roda?
      # app/controllers/jobs_controller.rb
      class JobsController < ApplicationController
        d...
Chainability:
           it “quacks” like named_scope

      Job.where(:title => 'Rails Developer')
      Job.order('creat...
Chainability:
           it “quacks” like named_scope

      Job.where(:title => 'Rails Developer')
      Job.order('creat...
Chainability:
           it “quacks” like named_scope

      Job.where(:title => 'Rails Developer')
      Job.order('creat...
ARel




Hugo Baraúna   blog.plataformatec.com   @hugobarauna
Bundler
               Router
               ActionMailer
               ActiveModel
               Responders
           ...
Unobtrusive Javascript




Hugo Baraúna          blog.plataformatec.com   @hugobarauna
Unobtrusive Javascript: Rails 2.3
 remote_form_for(@post)




 link_to 'Destroy', post, :confirm => 'Are you sure?',:metho...
Unobtrusive Javascript: Rails 2.3
 remote_form_for(@post)
 <form action="/posts" class="new_post" id="new_post" method="po...
Unobtrusive Javascript: Rails 2.3
 remote_form_for(@post)
 <form action="/posts" class="new_post" id="new_post" method="po...
Unobtrusive Javascript: Rails 3
 # Rails 2.3
 remote_form_for(@post)
 <form action="/posts" class="new_post" id="new_post"...
Unobtrusive Javascript: Rails 3
 # Rails 2.3
 remote_form_for(@post)
 <form action="/posts" class="new_post" id="new_post"...
Unobtrusive Javascript: Rails 3
 # Rails 2.3
 remote_form_for(@post)
 <form action="/posts" class="new_post" id="new_post"...
Unobtrusive Javascript: Rails 3
# Rails 2.3
link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete
<a hre...
Unobtrusive Javascript: Rails 3
# Rails 2.3
link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete
<a hre...
Unobtrusive Javascript: Rails 3
# Rails 2.3
link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete
<a hre...
JS Driver

               Markup com HTML 5 custom data attributes




                                JS Driver




     ...
JS Driver
           // public/javascripts/rails.js
           document.observe("dom:loaded", function() {
             fu...
JS para todos os gostos

  • Prototype: default

  • jQuery: http://github.com/rails/jquery-ujs

  • MooTools: http://moot...
Javascript no Rails 3




Hugo Baraúna         blog.plataformatec.com   @hugobarauna
Javascript no Rails 3


                  Agnosticismo de Javascript


HTML 5 custom data attributes        JS driver para...
Bundler
               Router
               ActionMailer
               ActiveModel
               Responders
           ...
XSS Protection




Hugo Baraúna      blog.plataformatec.com   @hugobarauna
XSS protection
                  Rails 2.3: unsafe por default
         <%= @job.title %>                      <%= h @job....
XSS protection
                  Rails 2.3: unsafe por default
         <%= @job.title %>                      <%= h @job....
XSS protection
                  Rails 2.3: unsafe por default
         <%= @job.title %>                      <%= h @job....
ActiveSupport::SafeBuffer
               guru/code$ rails console
               > a ="maybe dangerous"
               => ...
Helpers que retornam HTML
               module ApplicationHelper
                 def strong(content)
                   ...
Helpers que retornam HTML
               module ApplicationHelper
                 def strong(content)
                   ...
Helpers que retornam HTML
               module ApplicationHelper
                 def strong(content)
                   ...
Tem muito mais aqui!

               http://github.com/plataformatec




Hugo Baraúna           blog.plataformatec.com    ...
Tem muito mais aqui!

               http://github.com/plataformatec




   ID                          blog              ...
Upcoming SlideShare
Loading in...5
×

O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010

2,557

Published on

Palestra realizada por Hugo Baraúna (@hugobarauna) no evento Ruby on Rails no Mundo Real, em 23 de Maio de 2010 na cidade de São Paulo.

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,557
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
31
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Transcript of "O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010"

  1. 1. Rails 3 Hugo Baraúna blog.plataformatec.com @hugobarauna
  2. 2. Rails 3 ID blog twitter Hugo Baraúna blog.plataformatec.com @hugobarauna
  3. 3. Quem sou eu? • Hugo Baraúna • 24 anos • Engenharia de Computação na Politécnica da USP • Desenvolvedor Ruby e Rails há mais de 3 anos • Co-fundador e engenheiro da Plataforma Tecnologia Hugo Baraúna blog.plataformatec.com @hugobarauna
  4. 4. Hugo Baraúna blog.plataformatec.com @hugobarauna
  5. 5. Desevolvemos aplicações em Rails Coaching em Consultoria Rails e Agile Hugo Baraúna blog.plataformatec.com @hugobarauna
  6. 6. Arquitetura Rails 3 Rails ActionDispatch ActiveSupport Hugo Baraúna blog.plataformatec.com @hugobarauna
  7. 7. Arquitetura Todo o resto são Rails 3 Railties! Rails ActionDispatch ActiveSupport Hugo Baraúna blog.plataformatec.com @hugobarauna
  8. 8. Arquitetura Todo o resto são Rails 3 Railties! ActiveRecord Rails ActionView ActionDispatch outros... ActiveSupport ActionController ActionMailer Hugo Baraúna blog.plataformatec.com @hugobarauna
  9. 9. Vantagens do Rails 3 Hugo Baraúna blog.plataformatec.com @hugobarauna
  10. 10. Vantagens do Rails 3 Performance Hugo Baraúna blog.plataformatec.com @hugobarauna
  11. 11. Vantagens do Rails 3 Agnóstico Performance Hugo Baraúna blog.plataformatec.com @hugobarauna
  12. 12. Vantagens do Rails 3 Modularidade Agnóstico Performance Hugo Baraúna blog.plataformatec.com @hugobarauna
  13. 13. Instalação guru/code$ gem install tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n guru/code$ gem install rails --pre Hugo Baraúna blog.plataformatec.com @hugobarauna
  14. 14. rails command Rails 2.3 Rails 3 ruby script/server rails server ruby script/console rails console ruby script/generate rails generate ruby script/dbconsole rails dbconsole Hugo Baraúna blog.plataformatec.com @hugobarauna
  15. 15. blog/config.ru require ::File.expand_path('../config/environment', __FILE__) run Blog::Application Hugo Baraúna blog.plataformatec.com @hugobarauna
  16. 16. blog/config.ru require ::File.expand_path('../config/environment', __FILE__) run Blog::Application Hugo Baraúna blog.plataformatec.com @hugobarauna
  17. 17. blog/config/application.rb require File.expand_path('../boot', __FILE__) require 'rails/all' Bundler.require(:default, Rails.env) if defined?(Bundler) module Blog class Application < Rails::Application config.encoding = "utf-8" config.filter_parameters += [:password] end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  18. 18. blog/config/application.rb require File.expand_path('../boot', __FILE__) require 'rails/all' Bundler.require(:default, Rails.env) if defined?(Bundler) module Blog uma Rack App! class Application < Rails::Application config.encoding = "utf-8" config.filter_parameters += [:password] end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  19. 19. blog/config/application.rb require File.expand_path('../boot', __FILE__) require 'rails/all' Bundler.require(:default, Rails.env) if defined?(Bundler) module Blog class Application < Rails::Application config.encoding = "utf-8" config.filter_parameters += [:password] end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  20. 20. blog/config/application.rb require File.expand_path('../boot', __FILE__) require 'rails/all' Bundler.require(:default, Rails.env) if defined?(Bundler) module Blog class Application < Rails::Application config.encoding = "utf-8" config.filter_parameters += [:password] end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  21. 21. blog/config/boot.rb require 'rubygems' # Set up gems listed in the Gemfile. gemfile = File.expand_path('../../Gemfile', __FILE__) begin ENV['BUNDLE_GEMFILE'] = gemfile require 'bundler' Bundler.setup rescue Bundler::GemNotFound => e STDERR.puts e.message STDERR.puts "Try running `bundle install`." exit! end if File.exist?(gemfile) Hugo Baraúna blog.plataformatec.com @hugobarauna
  22. 22. blog/config/boot.rb require 'rubygems' # Set up gems listed in the Gemfile. gemfile = File.expand_path('../../Gemfile', __FILE__) begin ENV['BUNDLE_GEMFILE'] = gemfile require 'bundler' Bundler.setup rescue Bundler::GemNotFound => e STDERR.puts e.message STDERR.puts "Try running `bundle install`." exit! end if File.exist?(gemfile) Hugo Baraúna blog.plataformatec.com @hugobarauna
  23. 23. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  24. 24. Hugo Baraúna blog.plataformatec.com @hugobarauna
  25. 25. Biblioteca para gerenciamento de dependências Hugo Baraúna blog.plataformatec.com @hugobarauna
  26. 26. # Gemfile source 'http://rubygems.org' # Bundle edge Rails instead: gem 'rails', :git => 'git://github.com/rails/rails.git' gem 'mysql' gem 'devise', :git => 'git://github.com/plataformatec/ devise.git' gem 'responders', :git => 'git://github.com/plataformatec/ responders.git' group :development do gem 'ruby-debug' end group :test do gem 'rspec' gem 'rspec-rails', '>= 2.0.0.beta' end Hugo Baraúna blog.plataformatec.com @hugobarauna
  27. 27. # Gemfile source 'http://rubygems.org' # Bundle edge Rails instead: gem 'rails', :git => 'git://github.com/rails/rails.git' gem 'mysql' gem 'devise', :git => 'git://github.com/plataformatec/ devise.git' gem 'responders', :git => 'git://github.com/plataformatec/ responders.git' group :development do gem 'ruby-debug' end group :test do gem 'rspec' gem 'rspec-rails', '>= 2.0.0.beta' end Hugo Baraúna blog.plataformatec.com @hugobarauna
  28. 28. # Gemfile source 'http://rubygems.org' # Bundle edge Rails instead: gem 'rails', :git => 'git://github.com/rails/rails.git' gem 'mysql' gem 'devise', :git => 'git://github.com/plataformatec/ devise.git' gem 'responders', :git => 'git://github.com/plataformatec/ responders.git' group :development do gem 'ruby-debug' end group :test do gem 'rspec' gem 'rspec-rails', '>= 2.0.0.beta' end Hugo Baraúna blog.plataformatec.com @hugobarauna
  29. 29. Resolução de dependências Hugo Baraúna blog.plataformatec.com @hugobarauna
  30. 30. Resolução de dependências guru/code$ gem dependency actionpack -v="2.3.5" Gem actionpack-2.3.5 activesupport (= 2.3.5, runtime) rack (~> 1.0.0, runtime) guru/code$ gem dependency thin Gem thin-1.2.7 daemons (>= 1.0.9, runtime) eventmachine (>= 0.12.6, runtime) rack (>= 1.0.0, runtime) Hugo Baraúna blog.plataformatec.com @hugobarauna
  31. 31. Resolução de dependências guru/code$ gem dependency actionpack -v="2.3.5" Gem actionpack-2.3.5 activesupport (= 2.3.5, runtime) rack (~> 1.0.0, runtime) guru/code$ gem dependency thin Gem thin-1.2.7 daemons (>= 1.0.9, runtime) eventmachine (>= 0.12.6, runtime) rack (>= 1.0.0, runtime) Hugo Baraúna blog.plataformatec.com @hugobarauna
  32. 32. Resolução de dependências require "rubygems" require "thin" gem "actionpack", "2.3.5" Hugo Baraúna blog.plataformatec.com @hugobarauna
  33. 33. Resolução de dependências require "rubygems" require "thin" gem "actionpack", "2.3.5" can't activate rack (~> 1.0.0, runtime) for ["actionpack-2.3.5"], already activated rack-1.1.0 for ["thin-1.2.7"] (Gem::LoadError) Hugo Baraúna blog.plataformatec.com @hugobarauna
  34. 34. Gemfile # Gemfile gem "thin" gem "actionpack", "2.3.5" Hugo Baraúna blog.plataformatec.com @hugobarauna
  35. 35. Gemfile # Gemfile gem "thin" gem "actionpack", "2.3.5" guru/code$ bundle list Gems included by the bundle: * actionpack (2.3.5) * activesupport (2.3.5) * daemons (1.0.10) * eventmachine (0.12.10) * rack (1.0.1) * thin (1.2.7) Hugo Baraúna blog.plataformatec.com @hugobarauna
  36. 36. Gemfile # Gemfile gem "thin" gem "actionpack", "2.3.5" guru/code$ bundle list Gems included by the bundle: * actionpack (2.3.5) * activesupport (2.3.5) * daemons (1.0.10) * eventmachine (0.12.10) * rack (1.0.1) * thin (1.2.7) Hugo Baraúna blog.plataformatec.com @hugobarauna
  37. 37. Lock no $LOAD_PATH Hugo Baraúna blog.plataformatec.com @hugobarauna
  38. 38. Esqueci de colocar no config.gem! Hugo Baraúna blog.plataformatec.com @hugobarauna
  39. 39. Esqueci de colocar no config.gem! Hugo Baraúna blog.plataformatec.com @hugobarauna
  40. 40. } guru/code$ gem list *** LOCAL GEMS *** bundler (0.9.25) rake (0.8.7, 0.8.5) Filesystem rdoc (2.5.8) thor (0.13.6) Hugo Baraúna blog.plataformatec.com @hugobarauna
  41. 41. } guru/code$ gem list *** LOCAL GEMS *** bundler (0.9.25) rake (0.8.7, 0.8.5) Filesystem rdoc (2.5.8) thor (0.13.6) # Gemfile gem “rake”, “0.8.5” } Gemfile Hugo Baraúna blog.plataformatec.com @hugobarauna
  42. 42. } guru/code$ gem list *** LOCAL GEMS *** bundler (0.9.25) rake (0.8.7, 0.8.5) Filesystem rdoc (2.5.8) thor (0.13.6) # Gemfile gem “rake”, “0.8.5” } Gemfile rake-0.8.5 } $LOAD_PATH Hugo Baraúna blog.plataformatec.com @hugobarauna
  43. 43. guru/code$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) Hugo Baraúna blog.plataformatec.com @hugobarauna
  44. 44. guru/code$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) # Gemfile gem "rake" Hugo Baraúna blog.plataformatec.com @hugobarauna
  45. 45. guru/code$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) # Gemfile gem "rake" # test_load_path_lock.rb require "rubygems" require "bundler" Bundler.setup require "rake" require "thor" Hugo Baraúna blog.plataformatec.com @hugobarauna
  46. 46. guru/code$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) # Gemfile gem "rake" # test_load_path_lock.rb require "rubygems" require "bundler" Bundler.setup Lock no $LOAD_PATH require "rake" require "thor" Hugo Baraúna blog.plataformatec.com @hugobarauna
  47. 47. guru/code$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) # Gemfile gem "rake" # test_load_path_lock.rb require "rubygems" require "bundler" Bundler.setup Lock no $LOAD_PATH require "rake" require "thor" guru/code$ ruby test_load_path_lock.rb test_load_path_lock.rb:6:in `require': no such file to load -- thor (LoadError) from test_load_path_lock.rb:6 Hugo Baraúna blog.plataformatec.com @hugobarauna
  48. 48. guru/code$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) # Gemfile gem "rake" # test_load_path_lock.rb require "rubygems" require "bundler" Bundler.setup Lock no $LOAD_PATH require "rake" require "thor" guru/code$ ruby test_load_path_lock.rb test_load_path_lock.rb:6:in `require': no such file to load -- thor (LoadError) from test_load_path_lock.rb:6 Hugo Baraúna blog.plataformatec.com @hugobarauna
  49. 49. Hugo Baraúna blog.plataformatec.com @hugobarauna
  50. 50. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  51. 51. Router Hugo Baraúna blog.plataformatec.com @hugobarauna
  52. 52. Nova API Hugo Baraúna blog.plataformatec.com @hugobarauna
  53. 53. Rotas root Rails 2.3 map.root :controller => "welcome" Rails 3 root :to => "welcome#index" Hugo Baraúna blog.plataformatec.com @hugobarauna
  54. 54. Rotas comum Rails 2.3 map.connect "products/:id", controller=> "catalog", :action => "view" Rails 3 match 'products/:id' => 'catalog#view' Hugo Baraúna blog.plataformatec.com @hugobarauna
  55. 55. Named routes Rails 2.3 map.purchase "products/:id/purchase", :controller => "catalog", :action => "purchase" Rails 3 match "products/:id/purchase" => 'catalog#purchase', :as => :purchase Hugo Baraúna blog.plataformatec.com @hugobarauna
  56. 56. Resources com member e collection Rails 2.3 map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get } resources :products do Rails 3 member do get :short post :toggle end collection do get :sold end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  57. 57. Router and Rack FTW! Hugo Baraúna blog.plataformatec.com @hugobarauna
  58. 58. Rack FTW! Hugo Baraúna blog.plataformatec.com @hugobarauna
  59. 59. Rack FTW! match "posts/:echo" => "posts#show" Hugo Baraúna blog.plataformatec.com @hugobarauna
  60. 60. Rack FTW! match "posts/:echo" => "posts#show" uma Rack App! match "posts/:echo" => PostsController.action(:show) Hugo Baraúna blog.plataformatec.com @hugobarauna
  61. 61. Rack FTW! match "posts/:echo" => "posts#show" match "posts/:echo" => PostsController.action(:show) uma Rack App! match "posts/:echo" => lambda { |env| [ 200, {“Content-Type” => “plain/text”}, ["Echo!"] ] } Hugo Baraúna blog.plataformatec.com @hugobarauna
  62. 62. Rack FTW! match "posts/:echo" => "posts#show" match "posts/:echo" => PostsController.action(:show) match "posts/:echo" => lambda { |env| [ 200, {“Content-Type” => “plain/text”}, ["Echo!"] ] } uma Rack App! match "posts/:echo" => MySinatraBlog Hugo Baraúna blog.plataformatec.com @hugobarauna
  63. 63. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  64. 64. ActionMailer new API Hugo Baraúna blog.plataformatec.com @hugobarauna
  65. 65. ActionMailer new API guru/code$ rails g mailer Notifier signup_notification create app/mailers/notifier.rb invoke erb create app/views/notifier create app/views/notifier/signup_notification.text.erb invoke test_unit create test/functional/notifier_test.rb guru/code$ ls -lp app/ controllers/ helpers/ mailers/ models/ views/ Hugo Baraúna blog.plataformatec.com @hugobarauna
  66. 66. ActionMailer new API guru/code$ rails g mailer Notifier signup_notification create app/mailers/notifier.rb invoke erb create app/views/notifier create app/views/notifier/signup_notification.text.erb invoke test_unit create test/functional/notifier_test.rb guru/code$ ls -lp app/ controllers/ helpers/ mailers com diretório próprio mailers/ models/ views/ Hugo Baraúna blog.plataformatec.com @hugobarauna
  67. 67. ActionMailer new API class Notifier < ActionMailer::Base default :from => "system@example.com" def signup_notification(recipient) @account = recipient attachments['image.jpg'] = File.read ("image.jpg") mail(:to => recipient.email) do |format| format.html format.text end end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  68. 68. ActionMailer new API class Notifier < ActionMailer::Base Variáveis default :from => "system@example.com" de instância def signup_notification(recipient) @account = recipient attachments['image.jpg'] = File.read ("image.jpg") mail(:to => recipient.email) do |format| format.html format.text end end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  69. 69. ActionMailer new API class Notifier < ActionMailer::Base Variáveis default :from => "system@example.com" de instância def signup_notification(recipient) @account = recipient Attachments tipo attachments['image.jpg'] = File.read cookies ("image.jpg") mail(:to => recipient.email) do |format| format.html format.text end end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  70. 70. ActionMailer new API class Notifier < ActionMailer::Base Variáveis default :from => "system@example.com" de instância def signup_notification(recipient) @account = recipient Attachments tipo attachments['image.jpg'] = File.read cookies ("image.jpg") mail(:to => recipient.email) do |format| format.html format.text end end mail tipo respond_to do |format| end Hugo Baraúna blog.plataformatec.com @hugobarauna
  71. 71. AbstractController::Base ActionController::Metal ActionMailer::Base ActionController::Base Hugo Baraúna blog.plataformatec.com @hugobarauna
  72. 72. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  73. 73. ActiveModel Hugo Baraúna blog.plataformatec.com @hugobarauna
  74. 74. ActiveModel Hugo Baraúna blog.plataformatec.com @hugobarauna
  75. 75. ActiveModel • Google Summer of Code 2009: Hugo Baraúna blog.plataformatec.com @hugobarauna
  76. 76. ActiveModel • Google Summer of Code 2009: • Extraira lógica comum entre ActiveRecord e ActiveResource Hugo Baraúna blog.plataformatec.com @hugobarauna
  77. 77. ActiveModel • Google Summer of Code 2009: • Extraira lógica comum entre ActiveRecord e ActiveResource • Hoje Hugo Baraúna blog.plataformatec.com @hugobarauna
  78. 78. ActiveModel • Google Summer of Code 2009: • Extraira lógica comum entre ActiveRecord e ActiveResource • Hoje • Desempenha papel no agnosticismo de ORM Hugo Baraúna blog.plataformatec.com @hugobarauna
  79. 79. ActiveModel • Google Summer of Code 2009: • Extraira lógica comum entre ActiveRecord e ActiveResource • Hoje • Desempenha papel no agnosticismo de ORM • Permite a criação de models à la ActiveRecord Hugo Baraúna blog.plataformatec.com @hugobarauna
  80. 80. ActiveResource::Base + ActiveModel module ActiveResource ... class Base extend ActiveModel::Naming include CustomMethods, Observing, Validations include ActiveModel::Conversion include ActiveModel::Serializers::JSON include ActiveModel::Serializers::Xml end end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  81. 81. ActiveRecord::Base + ActiveModel Base.class_eval do ... extend ActiveModel::Naming ... include ActiveModel::Conversion include Validations ... include Callbacks, ActiveModel::Observing, Timestamp end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  82. 82. Agnosticismo de ORM Hugo Baraúna blog.plataformatec.com @hugobarauna
  83. 83. Agnosticismo de ORM Agnosticismo de ORM ActiveModel Rails::Railtie Hugo Baraúna blog.plataformatec.com @hugobarauna
  84. 84. Agnosticismo de ORM Agnosticismo de ORM ActiveModel Rails::Railtie Provê uma API para que o ActionPack possa conversar com o ORM Hugo Baraúna blog.plataformatec.com @hugobarauna
  85. 85. Agnosticismo de ORM Agnosticismo de ORM ActiveModel Rails::Railtie Provê uma API para que o Integração do ORM com o Rails ActionPack possa conversar com o ORM Hugo Baraúna blog.plataformatec.com @hugobarauna
  86. 86. ActiveModel::Lint::Tests Hugo Baraúna blog.plataformatec.com @hugobarauna
  87. 87. module ActiveModel module Lint module Tests def test_to_key assert model.respond_to?(:to_key), "The model should respond to to_key" def model.persisted?() false end assert model.to_key.nil? end def test_to_param assert model.respond_to?(:to_param), "The model should respond to to_param" def model.persisted?() false end assert model.to_param.nil? end def test_valid? assert model.respond_to?(:valid?), "The model should respond to valid?" assert_boolean model.valid?, "valid?" end ... def test_persisted? assert model.respond_to?(:persisted?), "The model should respond to persisted?" assert_boolean model.persisted?, "persisted?" end def test_errors_aref assert model.respond_to?(:errors), "The model should respond to errors" assert model.errors[:hello].is_a?(Array), "errors#[] should return an Array" end def test_errors_full_messages assert model.respond_to?(:errors), "The model should respond to errors" assert model.errors.full_messages.is_a?(Array), "errors#full_messages should return an Array" end end end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  88. 88. def test_to_param assert model.respond_to?(:to_param), "The model should respond to to_param" def model.persisted?() false end assert model.to_param.nil? end def test_valid? assert model.respond_to?(:valid?), "The model should respond to valid?" assert_boolean model.valid?, "valid?" end ... def test_errors_aref assert model.respond_to?(:errors), "The model should respond to errors" assert model.errors[:hello].is_a?(Array), "errors#[] should return an Array" end Hugo Baraúna blog.plataformatec.com @hugobarauna
  89. 89. ActiveRecord-like Ótimo exemplo de uso do ActiveModel http://github.com/plataformatec/mail_form Hugo Baraúna blog.plataformatec.com @hugobarauna
  90. 90. ActiveModel Hugo Baraúna blog.plataformatec.com @hugobarauna
  91. 91. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  92. 92. Responders Hugo Baraúna blog.plataformatec.com @hugobarauna
  93. 93. RAILS 2.3 def index @users = User.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @users } end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  94. 94. RAILS 2.3 def index @users = User.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @users } end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  95. 95. RAILS 3.0 respond_to :html, :xml def index @users = User.all respond_with(@users) end Hugo Baraúna blog.plataformatec.com @hugobarauna
  96. 96. RAILS 3.0 respond_to :html, :xml def index @users = User.all respond_with(@users) end Hugo Baraúna blog.plataformatec.com @hugobarauna
  97. 97. Navigational API GET POST PUT DELETE Hugo Baraúna blog.plataformatec.com @hugobarauna
  98. 98. Navigational API GET POST PUT DELETE Hugo Baraúna blog.plataformatec.com @hugobarauna
  99. 99. Navigational API GET POST PUT DELETE Hugo Baraúna blog.plataformatec.com @hugobarauna
  100. 100. respond_to :html, :xml def index @users = User.all respond_with(@users) end Hugo Baraúna blog.plataformatec.com @hugobarauna
  101. 101. Navigational API render GET render template collection.to_format POST PUT DELETE Hugo Baraúna blog.plataformatec.com @hugobarauna
  102. 102. RAILS 2.3 def create @user = User.new(params[:user]) respond_to do |format| if @user.save format.html { redirect_to @user, :notice => 'User was successfully created' } format.xml { render :xml => @user, :status => :created, :location => @user } else format.html { render :action => "new" } format.xml { render :xml => @user.errors, :status => :unprocessable_entity } end end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  103. 103. RAILS 3.0 def create @user = User.new(params[:user]) flash[:notice] = 'User was successfully created' if @user.save respond_with(@user) end Hugo Baraúna blog.plataformatec.com @hugobarauna
  104. 104. Navigational API render GET render template collection.to_format render Success redirect_to resource resource.to_format POST Failure render :new render resource.errors PUT DELETE Hugo Baraúna blog.plataformatec.com @hugobarauna
  105. 105. Navigational API render GET render template collection.to_format render Success redirect_to resource resource.to_format POST Failure render :new render resource.errors Success redirect_to resource head :ok PUT Failure render :edit render resource.errors DELETE redirect_to collection head :ok Hugo Baraúna blog.plataformatec.com @hugobarauna
  106. 106. respond_with(@users) ActionController::Responder Hugo Baraúna blog.plataformatec.com @hugobarauna
  107. 107. respond_with(@users) ActionController::Responder table.to_code Navigational API GET render template render collection.to_format Success redirect_to resource render resource.to_format POST Failure render :new render resource.errors Success redirect_to resource head :ok PUT Failure render :edit render resource.errors DELETE redirect_to collection head :ok Hugo Baraúna blog.plataformatec.com @hugobarauna
  108. 108. Responders Customizados Hugo Baraúna blog.plataformatec.com @hugobarauna
  109. 109. github.com/plataformatec/responders Hugo Baraúna blog.plataformatec.com @hugobarauna
  110. 110. github.com/plataformatec/responders Hugo Baraúna blog.plataformatec.com @hugobarauna
  111. 111. github.com/plataformatec/responders FlashResponder: seta o flash baseado na action do controller e no status do recurso Hugo Baraúna blog.plataformatec.com @hugobarauna
  112. 112. github.com/plataformatec/responders FlashResponder: seta o flash baseado na action do controller e no status do recurso HttpCacheResponder: automaticamente adiciona o cabeçalho HTTP Last-Modified para requests de API format Hugo Baraúna blog.plataformatec.com @hugobarauna
  113. 113. CONFIGURANDO O RESPONDERS # lib/application_responder.rb class ApplicationResponder < ActionController::Responder include Responders::FlashResponder include Responders::HttpCacheResponder end Hugo Baraúna blog.plataformatec.com @hugobarauna
  114. 114. CONFIGURANDO O RESPONDERS # lib/application_responder.rb class ApplicationResponder < ActionController::Responder include Responders::FlashResponder include Responders::HttpCacheResponder end # app/controllers/application_controller.rb class ApplicationController < ActionController::Base self.responder = ApplicationResponder respond_to :html protect_from_forgery layout 'application' end Hugo Baraúna blog.plataformatec.com @hugobarauna
  115. 115. SEM O RESPONDERS # app/controllers/users_controller.rb def create @user = User.new(params[:user]) flash[:notice] = 'User was successfully created' if @user.save respond_with(@user) end Hugo Baraúna blog.plataformatec.com @hugobarauna
  116. 116. SEM O RESPONDERS # app/controllers/users_controller.rb def create @user = User.new(params[:user]) flash[:notice] = 'User was successfully created' if @user.save respond_with(@user) end O FlashResponder vai fazer isso por mim Hugo Baraúna blog.plataformatec.com @hugobarauna
  117. 117. COM O RESPONDERS # app/controllers/users_controller.rb def create @user = User.new(params[:user]) @user.save respond_with(@user) end # config/locales/en.yml en: flash: users: create: success: “User was successfully created” Hugo Baraúna blog.plataformatec.com @hugobarauna
  118. 118. Responders Hugo Baraúna blog.plataformatec.com @hugobarauna
  119. 119. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  120. 120. ARel Hugo Baraúna blog.plataformatec.com @hugobarauna
  121. 121. Lazy loading # Rails 2.3 Job.find(:all, :conditions => {:published => true}) Faz um query no DB imediatamente e retorna um array de Jobs # Rails 3 Job.where(:published => true) Não faz query no DB, retorna um ActiveRecord::Relation Hugo Baraúna blog.plataformatec.com @hugobarauna
  122. 122. Onde a query roda? # app/controllers/jobs_controller.rb class JobsController < ApplicationController def index @jobs = Jobs.where(:published => true).order("created_at DESC") end end # app/views/jobs/index.html.erb <% cache do %> <% @jobs.each do |job| %> ... <% end %> <% end %> Hugo Baraúna blog.plataformatec.com @hugobarauna
  123. 123. Onde a query roda? # app/controllers/jobs_controller.rb class JobsController < ApplicationController def index @jobs = Jobs.where(:published => true).order("created_at DESC") end end Não realiza query no DB # app/views/jobs/index.html.erb <% cache do %> <% @jobs.each do |job| %> ... <% end %> <% end %> Hugo Baraúna blog.plataformatec.com @hugobarauna
  124. 124. Onde a query roda? # app/controllers/jobs_controller.rb class JobsController < ApplicationController def index @jobs = Jobs.where(:published => true).order("created_at DESC") end end Não realiza query no DB # app/views/jobs/index.html.erb <% cache do %> <% @jobs.each do |job| %> ... <% end %> <% end %> Só aqui que será feito a query no DB Hugo Baraúna blog.plataformatec.com @hugobarauna
  125. 125. Onde a query roda? # app/controllers/jobs_controller.rb class JobsController < ApplicationController def index @jobs = Jobs.where(:published => true).order("created_at DESC") end end Não realiza query no DB # app/views/jobs/index.html.erb Se estiver cacheado, não faz <% cache do %> a query no controller a toa <% @jobs.each do |job| %> ... <% end %> <% end %> Só aqui que será feito a query no DB Hugo Baraúna blog.plataformatec.com @hugobarauna
  126. 126. Chainability: it “quacks” like named_scope Job.where(:title => 'Rails Developer') Job.order('created_at DESC').limit(20).includes(:company) cars = Car.where(:colour => 'black') black_fancy_cars = cars.order('cars.price DESC').limit(10) black_cheap_cart = cars.order('cars.price ASC').limit(10) Hugo Baraúna blog.plataformatec.com @hugobarauna
  127. 127. Chainability: it “quacks” like named_scope Job.where(:title => 'Rails Developer') Job.order('created_at DESC').limit(20).includes(:company) ActiveRecord::Relation cars = Car.where(:colour => 'black') black_fancy_cars = cars.order('cars.price DESC').limit(10) black_cheap_cart = cars.order('cars.price ASC').limit(10) Hugo Baraúna blog.plataformatec.com @hugobarauna
  128. 128. Chainability: it “quacks” like named_scope Job.where(:title => 'Rails Developer') Job.order('created_at DESC').limit(20).includes(:company) ActiveRecord::Relation cars = Car.where(:colour => 'black') black_fancy_cars = cars.order('cars.price DESC').limit(10) black_cheap_cart = cars.order('cars.price ASC').limit(10) Reaproveitar uma Relation e encadear mais finders Hugo Baraúna blog.plataformatec.com @hugobarauna
  129. 129. ARel Hugo Baraúna blog.plataformatec.com @hugobarauna
  130. 130. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  131. 131. Unobtrusive Javascript Hugo Baraúna blog.plataformatec.com @hugobarauna
  132. 132. Unobtrusive Javascript: Rails 2.3 remote_form_for(@post) link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete Hugo Baraúna blog.plataformatec.com @hugobarauna
  133. 133. Unobtrusive Javascript: Rails 2.3 remote_form_for(@post) <form action="/posts" class="new_post" id="new_post" method="post" onsubmit="new Ajax.Request('/posts', {asynchronous:true, evalScripts:true, parameters:Form.serialize (this)}); return false;"> link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete Hugo Baraúna blog.plataformatec.com @hugobarauna
  134. 134. Unobtrusive Javascript: Rails 2.3 remote_form_for(@post) <form action="/posts" class="new_post" id="new_post" method="post" onsubmit="new Ajax.Request('/posts', {asynchronous:true, evalScripts:true, parameters:Form.serialize (this)}); return false;"> link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete <a href="/posts/1" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute ('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'LM2fEF6HuRWdYUZdEumWlemhI6iDPH97pqWhO4jEpiU='); f.appendChild(s);f.submit(); };return false;">Destroy</a> Hugo Baraúna blog.plataformatec.com @hugobarauna
  135. 135. Unobtrusive Javascript: Rails 3 # Rails 2.3 remote_form_for(@post) <form action="/posts" class="new_post" id="new_post" method="post" onsubmit="new Ajax.Request('/posts', {asynchronous:true, evalScripts:true, parameters:Form.serialize (this)}); return false;"> Hugo Baraúna blog.plataformatec.com @hugobarauna
  136. 136. Unobtrusive Javascript: Rails 3 # Rails 2.3 remote_form_for(@post) <form action="/posts" class="new_post" id="new_post" method="post" onsubmit="new Ajax.Request('/posts', {asynchronous:true, evalScripts:true, parameters:Form.serialize (this)}); return false;"> # Rails 3 form_for(@posts, :remote => true) <form action="/posts" class="new_post" data-remote="true" id="new_post" method="post"> Hugo Baraúna blog.plataformatec.com @hugobarauna
  137. 137. Unobtrusive Javascript: Rails 3 # Rails 2.3 remote_form_for(@post) <form action="/posts" class="new_post" id="new_post" method="post" onsubmit="new Ajax.Request('/posts', {asynchronous:true, evalScripts:true, parameters:Form.serialize (this)}); return false;"> # Rails 3 form_for(@posts, :remote => true) <form action="/posts" class="new_post" data-remote="true" id="new_post" method="post"> Hugo Baraúna blog.plataformatec.com @hugobarauna
  138. 138. Unobtrusive Javascript: Rails 3 # Rails 2.3 link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete <a href="/posts/1" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute ('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'LM2fEF6HuRWdYUZdEumWlemhI6iDPH97pqWhO4jEpiU='); f.appendChild(s);f.submit(); };return false;">Destroy</a> Hugo Baraúna blog.plataformatec.com @hugobarauna
  139. 139. Unobtrusive Javascript: Rails 3 # Rails 2.3 link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete <a href="/posts/1" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute ('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'LM2fEF6HuRWdYUZdEumWlemhI6iDPH97pqWhO4jEpiU='); f.appendChild(s);f.submit(); };return false;">Destroy</a> # Rails 3 link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete <a href="/posts/1" data-confirm="Are you sure?" data-method="delete" rel="nofollow">Destroy</a> Hugo Baraúna blog.plataformatec.com @hugobarauna
  140. 140. Unobtrusive Javascript: Rails 3 # Rails 2.3 link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete <a href="/posts/1" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute ('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'LM2fEF6HuRWdYUZdEumWlemhI6iDPH97pqWhO4jEpiU='); f.appendChild(s);f.submit(); };return false;">Destroy</a> # Rails 3 link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete <a href="/posts/1" data-confirm="Are you sure?" data-method="delete" rel="nofollow">Destroy</a> Hugo Baraúna blog.plataformatec.com @hugobarauna
  141. 141. JS Driver Markup com HTML 5 custom data attributes JS Driver JS Framework Hugo Baraúna blog.plataformatec.com @hugobarauna
  142. 142. JS Driver // public/javascripts/rails.js document.observe("dom:loaded", function() { function handleRemote(element) { var method, url, params; if (element.tagName.toLowerCase() === 'form') { Apenas 119 linhas! method = element.readAttribute('method') || 'post'; url = element.readAttribute('action'); params = element.serialize(true); } else { method = element.readAttribute('data-method') || 'get'; url = element.readAttribute('href'); params = {}; } var event = element.fire("ajax:before"); if (event.stopped) return false; new Ajax.Request(url, { method: method, parameters: params, asynchronous: true, evalScripts: true, onLoading: function(request) { element.fire("ajax:loading", {request: request}); }, onLoaded: function(request) { element.fire("ajax:loaded", {request: request}); }, onInteractive: function(request) { element.fire("ajax:interactive", {request: request}); }, onComplete: function(request) { element.fire("ajax:complete", {request: request}); }, onSuccess: function(request) { element.fire("ajax:success", {request: request}); }, onFailure: function(request) { element.fire("ajax:failure", {request: request}); } }); element.fire("ajax:after"); } ... Hugo Baraúna blog.plataformatec.com @hugobarauna
  143. 143. JS para todos os gostos • Prototype: default • jQuery: http://github.com/rails/jquery-ujs • MooTools: http://mootools.net/forge/p/rails_3_driver • Você pode fazer o seu! Hugo Baraúna blog.plataformatec.com @hugobarauna
  144. 144. Javascript no Rails 3 Hugo Baraúna blog.plataformatec.com @hugobarauna
  145. 145. Javascript no Rails 3 Agnosticismo de Javascript HTML 5 custom data attributes JS driver para cada framework Hugo Baraúna blog.plataformatec.com @hugobarauna
  146. 146. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  147. 147. XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  148. 148. XSS protection Rails 2.3: unsafe por default <%= @job.title %> <%= h @job.title %> unsafe safe Rails 3: safe por default <%= @job.title %> <%= raw @job.title %> safe unsafe Hugo Baraúna blog.plataformatec.com @hugobarauna
  149. 149. XSS protection Rails 2.3: unsafe por default <%= @job.title %> <%= h @job.title %> unsafe safe Rails 3: safe por default <%= @job.title %> <%= raw @job.title %> safe unsafe Hugo Baraúna blog.plataformatec.com @hugobarauna
  150. 150. XSS protection Rails 2.3: unsafe por default <%= @job.title %> <%= h @job.title %> unsafe safe Rails 3: safe por default <%= @job.title %> <%= raw @job.title %> safe unsafe Hugo Baraúna blog.plataformatec.com @hugobarauna
  151. 151. ActiveSupport::SafeBuffer guru/code$ rails console > a ="maybe dangerous" => "maybe dangerous" > a.html_safe? => false > b = a.html_safe => "maybe dangerous" > b.html_safe? => true > b.class => ActiveSupport::SafeBuffer Hugo Baraúna blog.plataformatec.com @hugobarauna
  152. 152. Helpers que retornam HTML module ApplicationHelper def strong(content) "<strong>#{h content}</string>".html_safe end end Hugo Baraúna blog.plataformatec.com @hugobarauna
  153. 153. Helpers que retornam HTML module ApplicationHelper def strong(content) "<strong>#{h content}</string>".html_safe end end Dicas: 1. Certificar-se de que todo input está sendo escapado Hugo Baraúna blog.plataformatec.com @hugobarauna
  154. 154. Helpers que retornam HTML module ApplicationHelper def strong(content) "<strong>#{h content}</string>".html_safe end end Dicas: 1. Certificar-se de que todo input está sendo escapado 2. Chamar html_safe no output Hugo Baraúna blog.plataformatec.com @hugobarauna
  155. 155. Tem muito mais aqui! http://github.com/plataformatec Hugo Baraúna blog.plataformatec.com @hugobarauna
  156. 156. Tem muito mais aqui! http://github.com/plataformatec ID blog twitter Hugo Baraúna blog.plataformatec.com @hugobarauna
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×