O que há de novo no Rails 3

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

description

Palestra sobre Rails 3 realizada no dia 29 de maio de 2010 no evento Ruby e Rails no Mundo Real em São Paulo.

Transcript of O que há de novo no Rails 3

Page 1: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Rails 3

Page 2: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

blog twitterID

Rails 3

Page 3: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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

Page 4: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Page 5: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Desevolvemosaplicações em Rails

ConsultoriaCoaching em Rails e Agile

Page 6: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Arquitetura

ActionDispatch

ActiveSupport

Rails

Rails 3

Page 7: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Arquitetura

ActionDispatch

ActiveSupport

Rails

Rails 3

Todo o resto são Railties!

Page 8: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Arquitetura

ActionDispatch

ActiveSupport

Rails

Rails 3

Todo o resto são Railties!

ActiveRecord

ActionMailer

ActionController

ActionView

outros...

Page 9: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Vantagens do Rails 3

Page 10: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Vantagens do Rails 3

Performance

Page 11: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Vantagens do Rails 3

Performance

Agnóstico

Page 12: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Vantagens do Rails 3

Performance

Modularidade

Agnóstico

Page 13: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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

Page 14: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

rails command

ruby script/serverruby script/consoleruby script/generateruby script/dbconsole

rails consolerails generaterails dbconsole

rails server

Rails 2.3 Rails 3

Page 15: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

blog/config.ru

require ::File.expand_path('../config/environment', __FILE__)run Blog::Application

Page 16: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

blog/config.ru

require ::File.expand_path('../config/environment', __FILE__)run Blog::Application

Page 17: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

blog/config/application.rbrequire 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] endend

Page 18: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

blog/config/application.rbrequire 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] endend

uma Rack App!

Page 19: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

blog/config/application.rbrequire 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] endend

Page 20: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

blog/config/application.rbrequire 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] endend

Page 21: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

blog/config/boot.rbrequire 'rubygems'

# Set up gems listed in the Gemfile.gemfile = File.expand_path('../../Gemfile', __FILE__)begin ENV['BUNDLE_GEMFILE'] = gemfile require 'bundler' Bundler.setuprescue Bundler::GemNotFound => e STDERR.puts e.message STDERR.puts "Try running `bundle install`." exit!end if File.exist?(gemfile)

Page 22: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

blog/config/boot.rbrequire 'rubygems'

# Set up gems listed in the Gemfile.gemfile = File.expand_path('../../Gemfile', __FILE__)begin ENV['BUNDLE_GEMFILE'] = gemfile require 'bundler' Bundler.setuprescue Bundler::GemNotFound => e STDERR.puts e.message STDERR.puts "Try running `bundle install`." exit!end if File.exist?(gemfile)

Page 23: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

BundlerRouterActionMailerActiveModelRespondersARelUnobtrusive JavascriptXSS Protection

Page 24: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Page 25: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Biblioteca para gerenciamento de dependências

Page 26: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

# Gemfilesource '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

Page 27: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

# Gemfilesource '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

Page 28: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

# Gemfilesource '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

Page 29: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Resolução de dependências

Page 30: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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 thinGem thin-1.2.7 daemons (>= 1.0.9, runtime) eventmachine (>= 0.12.6, runtime) rack (>= 1.0.0, runtime)

Resolução de dependências

Page 31: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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 thinGem thin-1.2.7 daemons (>= 1.0.9, runtime) eventmachine (>= 0.12.6, runtime) rack (>= 1.0.0, runtime)

Resolução de dependências

Page 32: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Resolução de dependências

require "rubygems"require "thin"gem "actionpack", "2.3.5"

Page 33: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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)

Page 34: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Gemfile# Gemfilegem "thin"gem "actionpack", "2.3.5"

Page 35: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Gemfile# Gemfilegem "thin"gem "actionpack", "2.3.5"

guru/code$ bundle listGems 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)

Page 36: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Gemfile# Gemfilegem "thin"gem "actionpack", "2.3.5"

guru/code$ bundle listGems 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)

Page 37: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Lock no $LOAD_PATH

Page 38: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Esqueci de colocar no config.gem!

Page 39: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Esqueci de colocar no config.gem!

Page 40: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

guru/code$ gem list*** LOCAL GEMS ***

bundler (0.9.25)rake (0.8.7, 0.8.5)rdoc (2.5.8)thor (0.13.6)

} Filesystem

Page 41: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

guru/code$ gem list*** LOCAL GEMS ***

bundler (0.9.25)rake (0.8.7, 0.8.5)rdoc (2.5.8)thor (0.13.6)

} Filesystem

# Gemfilegem “rake”, “0.8.5” } Gemfile

Page 42: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

guru/code$ gem list*** LOCAL GEMS ***

bundler (0.9.25)rake (0.8.7, 0.8.5)rdoc (2.5.8)thor (0.13.6)

} Filesystem

# Gemfilegem “rake”, “0.8.5” } Gemfile

rake-0.8.5 } $LOAD_PATH

Page 43: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

guru/code$ gem listrake (0.8.7, 0.8.5)thor (0.13.6)

Page 44: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

# Gemfilegem "rake"

guru/code$ gem listrake (0.8.7, 0.8.5)thor (0.13.6)

Page 45: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

# Gemfilegem "rake"

# test_load_path_lock.rbrequire "rubygems"require "bundler"Bundler.setuprequire "rake"require "thor"

guru/code$ gem listrake (0.8.7, 0.8.5)thor (0.13.6)

Page 46: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

# Gemfilegem "rake"

# test_load_path_lock.rbrequire "rubygems"require "bundler"Bundler.setuprequire "rake"require "thor"

guru/code$ gem listrake (0.8.7, 0.8.5)thor (0.13.6)

Lock no $LOAD_PATH

Page 47: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

# Gemfilegem "rake"

# test_load_path_lock.rbrequire "rubygems"require "bundler"Bundler.setuprequire "rake"require "thor"

guru/code$ gem listrake (0.8.7, 0.8.5)thor (0.13.6)

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

Lock no $LOAD_PATH

Page 48: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

# Gemfilegem "rake"

# test_load_path_lock.rbrequire "rubygems"require "bundler"Bundler.setuprequire "rake"require "thor"

guru/code$ gem listrake (0.8.7, 0.8.5)thor (0.13.6)

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

Lock no $LOAD_PATH

Page 49: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Page 50: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

BundlerRouterActionMailerActiveModelRespondersARelUnobtrusive JavascriptXSS Protection

Page 51: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Router

Page 52: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Nova API

Page 53: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Rotas rootRails 2.3

Rails 3

map.root :controller => "welcome"

root :to => "welcome#index"

Page 54: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Rotas comumRails 2.3

Rails 3

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

match 'products/:id' => 'catalog#view'

Page 55: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Named routesRails 2.3

Rails 3

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

match "products/:id/purchase" => 'catalog#purchase', :as => :purchase

Page 56: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Resources com member e collection

Rails 2.3

Rails 3

map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }

resources :products do member do get :short post :toggle end

collection do get :sold endend

Page 57: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Router and Rack FTW!

Page 58: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Rack FTW!

Page 59: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Rack FTW!

match "posts/:echo" => "posts#show"

Page 60: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Rack FTW!

match "posts/:echo" => "posts#show"

match "posts/:echo" => PostsController.action(:show)

uma Rack App!

Page 61: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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!

Page 62: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Rack FTW!

match "posts/:echo" => "posts#show"

match "posts/:echo" => PostsController.action(:show)

match "posts/:echo" => MySinatraBlog

match "posts/:echo" => lambda { |env| [ 200, {“Content-Type” => “plain/text”}, ["Echo!"] ] }

uma Rack App!

Page 63: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

BundlerRouterActionMailerActiveModelRespondersARelUnobtrusive JavascriptXSS Protection

Page 64: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActionMailer new API

Page 65: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActionMailer new API

guru/code$ ls -lp app/ controllers/ helpers/ mailers/ models/ views/

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

Page 66: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActionMailer new API

guru/code$ ls -lp app/ controllers/ helpers/ mailers/ models/ views/

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

mailers com diretório próprio

Page 67: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

class Notifier < ActionMailer::Base default :from => "[email protected]" def signup_notification(recipient) @account = recipient attachments['image.jpg'] = File.read("image.jpg") mail(:to => recipient.email) do |format| format.html format.text end endend

ActionMailer new API

Page 68: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

class Notifier < ActionMailer::Base default :from => "[email protected]" def signup_notification(recipient) @account = recipient attachments['image.jpg'] = File.read("image.jpg") mail(:to => recipient.email) do |format| format.html format.text end endend

Variáveisde

instância

ActionMailer new API

Page 69: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

class Notifier < ActionMailer::Base default :from => "[email protected]" def signup_notification(recipient) @account = recipient attachments['image.jpg'] = File.read("image.jpg") mail(:to => recipient.email) do |format| format.html format.text end endend

Variáveisde

instânciaAttachments tipo

cookies

ActionMailer new API

Page 70: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

class Notifier < ActionMailer::Base default :from => "[email protected]" def signup_notification(recipient) @account = recipient attachments['image.jpg'] = File.read("image.jpg") mail(:to => recipient.email) do |format| format.html format.text end endend

Variáveisde

instânciaAttachments tipo

cookies

mail tipo respond_to do |format|

ActionMailer new API

Page 71: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActionMailer ::Base ActionController ::Base

ActionController ::Metal

AbstractController ::Base

Page 72: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

BundlerRouterActionMailerActiveModelRespondersARelUnobtrusive JavascriptXSS Protection

Page 73: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel

Page 74: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel

Page 75: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel

• Google Summer of Code 2009:

Page 76: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel

• Google Summer of Code 2009:

• Extrair a lógica comum entre ActiveRecord e ActiveResource

Page 77: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel

• Google Summer of Code 2009:

• Extrair a lógica comum entre ActiveRecord e ActiveResource

• Hoje

Page 78: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel

• Google Summer of Code 2009:

• Extrair a lógica comum entre ActiveRecord e ActiveResource

• Hoje

•Desempenha papel no agnosticismo de ORM

Page 79: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel

• Google Summer of Code 2009:

• Extrair a lógica comum entre ActiveRecord e ActiveResource

• Hoje

•Desempenha papel no agnosticismo de ORM

• Permite a criação de models à la ActiveRecord

Page 80: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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 endend

Page 81: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveRecord::Base + ActiveModel

Base.class_eval do ... extend ActiveModel::Naming ... include ActiveModel::Conversion include Validations ... include Callbacks, ActiveModel::Observing, Timestamp endend

Page 82: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Agnosticismo de ORM

Page 83: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel Rails::Railtie

Agnosticismo de ORM

Agnosticismo de ORM

Page 84: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel Rails::Railtie

Agnosticismo de ORM

Agnosticismo de ORM

Provê uma API para que o ActionPack possa conversar com o

ORM

Page 85: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel Rails::Railtie

Agnosticismo de ORM

Agnosticismo de ORM

Integração do ORM com o RailsProvê uma API para que o ActionPack possa conversar com o

ORM

Page 86: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel::Lint::Tests

Page 87: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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 endend

Page 88: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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

Page 89: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveRecord-like

http://github.com/plataformatec/mail_form

Ótimo exemplo de uso do ActiveModel

Page 90: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ActiveModel

Page 91: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

BundlerRouterActionMailerActiveModelRespondersARelUnobtrusive JavascriptXSS Protection

Page 92: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Responders

Page 93: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

RAILS 2.3

def index @users = User.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @users } endend

Page 94: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

RAILS 2.3

def index @users = User.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @users } endend

Page 95: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

RAILS 3.0

respond_to :html, :xml

def index @users = User.all respond_with(@users)end

Page 96: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

RAILS 3.0

respond_to :html, :xml

def index @users = User.all respond_with(@users)end

Page 97: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Navigational API

GET

POST

PUT

DELETE

Page 98: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Navigational API

GET

POST

PUT

DELETE

Page 99: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Navigational API

GET

POST

PUT

DELETE

Page 100: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

respond_to :html, :xml

def index @users = User.all respond_with(@users)end

Page 101: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Navigational API

GET render template render collection.to_format

POST

PUT

DELETE

Page 102: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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 endend

RAILS 2.3

Page 103: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

RAILS 3.0

def create @user = User.new(params[:user]) flash[:notice] = 'User was successfully created' if @user.save respond_with(@user)end

Page 104: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Navigational API

GETGET render template render collection.to_format

POSTSuccess redirect_to resource render

resource.to_formatPOST

Failure render :new render resource.errors

PUTPUT

DELETEDELETE

Page 105: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Navigational API

GETGET render template render collection.to_format

POSTSuccess redirect_to resource render

resource.to_formatPOST

Failure render :new render resource.errors

PUTSuccess redirect_to resource head :ok

PUTFailure render :edit render resource.errors

DELETEDELETE redirect_to collection head :ok

Page 106: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

respond_with(@users)

ActionController ::Responder

Page 107: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

respond_with(@users)

Navigational API

GETGET render template render collection.to_format

POST

Success redirect_to resource render resource.to_format

POSTFailure render :new render resource.errors

PUT

Success redirect_to resource head :ok

PUTFailure render :edit render resource.errors

DELETEDELETE redirect_to collection head :ok

table.to_code

ActionController ::Responder

Page 108: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Responders Customizados

Page 109: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

github.com/plataformatec/responders

Page 110: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

github.com/plataformatec/responders

Page 111: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

github.com/plataformatec/responders

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

Page 112: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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

Page 113: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

# lib/application_responder.rbclass ApplicationResponder < ActionController::Responder include Responders::FlashResponder include Responders::HttpCacheResponderend

CONFIGURANDO O RESPONDERS

Page 114: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

# lib/application_responder.rbclass ApplicationResponder < ActionController::Responder include Responders::FlashResponder include Responders::HttpCacheResponderend

CONFIGURANDO O RESPONDERS

# app/controllers/application_controller.rbclass ApplicationController < ActionController::Base self.responder = ApplicationResponder respond_to :html

protect_from_forgery layout 'application'end

Page 115: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

SEM O RESPONDERS

# app/controllers/users_controller.rbdef create @user = User.new(params[:user]) flash[:notice] = 'User was successfully created' if @user.save respond_with(@user)end

Page 116: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

SEM O RESPONDERS

# app/controllers/users_controller.rbdef 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

Page 117: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

COM O RESPONDERS

# app/controllers/users_controller.rbdef create @user = User.new(params[:user]) @user.save respond_with(@user)end

# config/locales/en.ymlen: flash: users: create: success: “User was successfully created”

Page 118: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Responders

Page 119: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

BundlerRouterActionMailerActiveModelRespondersARelUnobtrusive JavascriptXSS Protection

Page 120: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ARel

Page 121: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Lazy loading# Rails 2.3Job.find(:all, :conditions => {:published => true})

# Rails 3Job.where(:published => true)

Faz um query no DB imediatamente e retorna um array de Jobs

Não faz query no DB, retorna um ActiveRecord::Relation

Page 122: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Onde a query roda?# app/controllers/jobs_controller.rbclass JobsController < ApplicationController def index @jobs = Jobs.where(:published => true).order("created_at DESC") endend

# app/views/jobs/index.html.erb<% cache do %> <% @jobs.each do |job| %> ... <% end %><% end %>

Page 123: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Onde a query roda?# app/controllers/jobs_controller.rbclass JobsController < ApplicationController def index @jobs = Jobs.where(:published => true).order("created_at DESC") endend

# app/views/jobs/index.html.erb<% cache do %> <% @jobs.each do |job| %> ... <% end %><% end %>

Não realiza query no DB

Page 124: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Onde a query roda?# app/controllers/jobs_controller.rbclass JobsController < ApplicationController def index @jobs = Jobs.where(:published => true).order("created_at DESC") endend

# app/views/jobs/index.html.erb<% cache do %> <% @jobs.each do |job| %> ... <% end %><% end %>

Só aqui que será feito a query no DB

Não realiza query no DB

Page 125: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Onde a query roda?# app/controllers/jobs_controller.rbclass JobsController < ApplicationController def index @jobs = Jobs.where(:published => true).order("created_at DESC") endend

# app/views/jobs/index.html.erb<% cache do %> <% @jobs.each do |job| %> ... <% end %><% end %>

Só aqui que será feito a query no DB

Não realiza query no DB

Se estiver cacheado, não faz a query no controller a toa

Page 126: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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)

Page 127: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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)

ActiveRecord::Relation

Page 128: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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)

ActiveRecord::Relation

Reaproveitar uma Relation e encadear mais finders

Page 129: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

ARel

Page 130: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

BundlerRouterActionMailerActiveModelRespondersARelUnobtrusive JavascriptXSS Protection

Page 131: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Unobtrusive Javascript

Page 132: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

remote_form_for(@post)

Unobtrusive Javascript: Rails 2.3

link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete

Page 133: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

remote_form_for(@post)

Unobtrusive Javascript: Rails 2.3

<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

Page 134: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

remote_form_for(@post)

Unobtrusive Javascript: Rails 2.3

<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>

Page 135: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Unobtrusive Javascript: Rails 3# Rails 2.3remote_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;">

Page 136: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Unobtrusive Javascript: Rails 3# Rails 2.3remote_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 3form_for(@posts, :remote => true)

<form action="/posts" class="new_post" data-remote="true" id="new_post" method="post">

Page 137: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Unobtrusive Javascript: Rails 3# Rails 2.3remote_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 3form_for(@posts, :remote => true)

<form action="/posts" class="new_post" data-remote="true" id="new_post" method="post">

Page 138: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Unobtrusive Javascript: Rails 3# Rails 2.3link_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>

Page 139: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Unobtrusive Javascript: Rails 3# Rails 2.3link_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 3link_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>

Page 140: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Unobtrusive Javascript: Rails 3# Rails 2.3link_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 3link_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>

Page 141: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

JS Driver

Markup com HTML 5 custom data attributes

JS Driver

JS Framework

Page 142: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

JS Driver// public/javascripts/rails.jsdocument.observe("dom:loaded", function() { function handleRemote(element) { var method, url, params;

if (element.tagName.toLowerCase() === 'form') { 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"); } ...

Apenas 119 linhas!

Page 143: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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!

Page 144: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Javascript no Rails 3

Page 145: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

HTML 5 custom data attributes JS driver para cada framework

Agnosticismo de Javascript

Javascript no Rails 3

Page 146: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

BundlerRouterActionMailerActiveModelRespondersARelUnobtrusive JavascriptXSS Protection

Page 147: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

XSS Protection

Page 148: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

XSS protection

<%= @job.title %> <%= h @job.title %>

Rails 2.3: unsafe por default

safeunsafe

<%= @job.title %> <%= raw @job.title %>

Rails 3: safe por default

safe unsafe

Page 149: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

XSS protection

<%= @job.title %> <%= h @job.title %>

Rails 2.3: unsafe por default

safeunsafe

<%= @job.title %> <%= raw @job.title %>

Rails 3: safe por default

safe unsafe

Page 150: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

XSS protection

<%= @job.title %> <%= h @job.title %>

Rails 2.3: unsafe por default

safeunsafe

<%= @job.title %> <%= raw @job.title %>

Rails 3: safe por default

safe unsafe

Page 151: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

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

Page 152: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Helpers que retornam HTML

module ApplicationHelper def strong(content) "<strong>#{h content}</string>".html_safe endend

Page 153: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Helpers que retornam HTML

module ApplicationHelper def strong(content) "<strong>#{h content}</string>".html_safe endend

Dicas:1. Certificar-se de que todo input está sendo escapado

Page 154: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

Helpers que retornam HTML

module ApplicationHelper def strong(content) "<strong>#{h content}</string>".html_safe endend

Dicas:1. Certificar-se de que todo input está sendo escapado

2. Chamar html_safe no output

Page 155: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

http://github.com/plataformatec

Tem muito mais aqui!

Page 156: O que há de novo no Rails 3

Hugo Baraúna @hugobaraunablog.plataformatec.com

blog twitterID

http://github.com/plataformatec

Tem muito mais aqui!