O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

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

  • 2,917 views
Uploaded 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.

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.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,917
On Slideshare
1,981
From Embeds
936
Number of Embeds
6

Actions

Shares
Downloads
30
Comments
0
Likes
2

Embeds 936

http://blog.plataformatec.com.br 831
http://feeds.feedburner.com 95
http://www.vitornascimento.com.br 5
http://localhost 3
http://static.slidesharecdn.com 1
http://translate.googleusercontent.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Rails 3 Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 2. Rails 3 ID blog twitter Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 5. Desevolvemos aplicações em Rails Coaching em Consultoria Rails e Agile Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 6. Arquitetura Rails 3 Rails ActionDispatch ActiveSupport Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 7. Arquitetura Todo o resto são Rails 3 Railties! Rails ActionDispatch ActiveSupport Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. Vantagens do Rails 3 Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 10. Vantagens do Rails 3 Performance Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 11. Vantagens do Rails 3 Agnóstico Performance Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 12. Vantagens do Rails 3 Modularidade Agnóstico Performance Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. blog/config.ru require ::File.expand_path('../config/environment', __FILE__) run Blog::Application Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 16. blog/config.ru require ::File.expand_path('../config/environment', __FILE__) run Blog::Application Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. 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. 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. 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. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 24. Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 25. Biblioteca para gerenciamento de dependências Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. # 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. # 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. Resolução de dependências Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. Resolução de dependências require "rubygems" require "thin" gem "actionpack", "2.3.5" Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. Gemfile # Gemfile gem "thin" gem "actionpack", "2.3.5" Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. Lock no $LOAD_PATH Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 38. Esqueci de colocar no config.gem! Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 39. Esqueci de colocar no config.gem! Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. } 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. } 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. guru/code$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. 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. 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. Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 50. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 51. Router Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 52. Nova API Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 53. Rotas root Rails 2.3 map.root :controller => "welcome" Rails 3 root :to => "welcome#index" Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. Router and Rack FTW! Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 58. Rack FTW! Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 59. Rack FTW! match "posts/:echo" => "posts#show" Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 64. ActionMailer new API Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. 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. 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. 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. AbstractController::Base ActionController::Metal ActionMailer::Base ActionController::Base Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 72. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 73. ActiveModel Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 74. ActiveModel Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 75. ActiveModel • Google Summer of Code 2009: Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 76. ActiveModel • Google Summer of Code 2009: • Extraira lógica comum entre ActiveRecord e ActiveResource Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 77. ActiveModel • Google Summer of Code 2009: • Extraira lógica comum entre ActiveRecord e ActiveResource • Hoje Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. 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. Agnosticismo de ORM Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 83. Agnosticismo de ORM Agnosticismo de ORM ActiveModel Rails::Railtie Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. ActiveModel::Lint::Tests Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. ActiveRecord-like Ótimo exemplo de uso do ActiveModel http://github.com/plataformatec/mail_form Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 90. ActiveModel Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 91. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 92. Responders Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. RAILS 3.0 respond_to :html, :xml def index @users = User.all respond_with(@users) end Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. Navigational API GET POST PUT DELETE Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 98. Navigational API GET POST PUT DELETE Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 99. Navigational API GET POST PUT DELETE Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 100. respond_to :html, :xml def index @users = User.all respond_with(@users) end Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 101. Navigational API render GET render template collection.to_format POST PUT DELETE Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. 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. respond_with(@users) ActionController::Responder Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. Responders Customizados Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 109. github.com/plataformatec/responders Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 110. github.com/plataformatec/responders Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. 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. 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. 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. 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. Responders Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 119. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 120. ARel Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. 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. 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. 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. 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. 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. ARel Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 130. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 131. Unobtrusive Javascript Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. JS Driver Markup com HTML 5 custom data attributes JS Driver JS Framework Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. Javascript no Rails 3 Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. Bundler Router ActionMailer ActiveModel Responders ARel Unobtrusive Javascript XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 147. XSS Protection Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 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. 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. 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. 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. 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. 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. 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. Tem muito mais aqui! http://github.com/plataformatec Hugo Baraúna blog.plataformatec.com @hugobarauna
  • 156. Tem muito mais aqui! http://github.com/plataformatec ID blog twitter Hugo Baraúna blog.plataformatec.com @hugobarauna