Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails 3 @ RS on Rails 2010

Rails 3 @ RS on Rails 2010

Carlos Antonio

August 21, 2010
Tweet

More Decks by Carlos Antonio

Other Decks in Programming

Transcript

  1. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Quem sou eu? • Carlos Antonio

    da Silva • Desenvolvedor Ruby e Rails há mais de 2 anos • Engenheiro da Plataforma Tecnologia a 1 ano Sunday, November 6, 11
  2. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Arquitetura ActionDispatch ActiveSupport Rails Todo o

    resto são Railties! ActiveRecord ActionMailer ActionController ActionView outros... Sunday, November 6, 11
  3. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br rails command ruby script/server ruby script/console

    ruby script/generate ruby script/dbconsole rails console rails generate rails dbconsole rails server Rails 2.3 Rails 3 Sunday, November 6, 11
  4. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br rails command rails server rails console

    rails generate rails dbconsole rails c rails g rails db rails s Rails 3 Shortcuts! Sunday, November 6, 11
  5. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 Sunday, November 6, 11
  6. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 uma Rack App! Sunday, November 6, 11
  7. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br O que é uma Rack App?

    Qualquer objeto que responde ao método call, retornando um array com três parâmetros: o response status, os headers e o body, que por sua vez deve responder ao método each. Rack App! lambda { |env| [ 200, {“Content-Type” => “plain/text”}, ["Hello!"] ] } Sunday, November 6, 11
  8. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 uma Rack App! Sunday, November 6, 11
  9. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 Sunday, November 6, 11
  10. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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) Sunday, November 6, 11
  11. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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) Sunday, November 6, 11
  12. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br rsrails$ gem dependency actionpack -v="2.3.5" Gem

    actionpack-2.3.5 activesupport (= 2.3.5, runtime) rack (~> 1.0.0, runtime) rsrails$ gem dependency thin Gem thin-1.2.7 daemons (>= 1.0.9, runtime) eventmachine (>= 0.12.6, runtime) rack (>= 1.0.0, runtime) Rubygems Resolução de dependências Sunday, November 6, 11
  13. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br rsrails$ gem dependency actionpack -v="2.3.5" Gem

    actionpack-2.3.5 activesupport (= 2.3.5, runtime) rack (~> 1.0.0, runtime) rsrails$ gem dependency thin Gem thin-1.2.7 daemons (>= 1.0.9, runtime) eventmachine (>= 0.12.6, runtime) rack (>= 1.0.0, runtime) Rubygems Resolução de dependências Sunday, November 6, 11
  14. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rubygems Resolução de dependências require "rubygems"

    require "thin" gem "actionpack", "2.3.5" Gems instaladas do rack: * rack (1.0.1) * rack (1.1.0) Sunday, November 6, 11
  15. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rubygems Resolução de dependências require "rubygems"

    require "thin" gem "actionpack", "2.3.5" BOOM!!! Gems instaladas do rack: * rack (1.0.1) * rack (1.1.0) Sunday, November 6, 11
  16. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rubygems 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) Gems instaladas do rack: * rack (1.0.1) * rack (1.1.0) Sunday, November 6, 11
  17. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rubygems 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) Gems instaladas do rack: * rack (1.0.1) * rack (1.1.0) Sunday, November 6, 11
  18. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rubygems 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) Gems instaladas do rack: * rack (1.0.1) * rack (1.1.0) Sunday, November 6, 11
  19. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Bundler: Gemfile # Gemfile gem "thin"

    gem "actionpack", "2.3.5" rsrails$ 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) Sunday, November 6, 11
  20. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Bundler: Gemfile # Gemfile gem "thin"

    gem "actionpack", "2.3.5" rsrails$ 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) Sunday, November 6, 11
  21. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br rsrails$ gem list *** LOCAL GEMS

    *** bundler (0.9.25) rake (0.8.7, 0.8.5) rdoc (2.5.8) thor (0.13.6) } Filesystem Sunday, November 6, 11
  22. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br rsrails$ gem list *** LOCAL GEMS

    *** bundler (0.9.25) rake (0.8.7, 0.8.5) rdoc (2.5.8) thor (0.13.6) } Filesystem # Rubygems gem “rake”, “0.8.5” } Gemfile Sunday, November 6, 11
  23. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br rsrails$ gem list *** LOCAL GEMS

    *** bundler (0.9.25) rake (0.8.7, 0.8.5) rdoc (2.5.8) thor (0.13.6) } Filesystem # Rubygems gem “rake”, “0.8.5” } Gemfile bundler (0.9.25) rake (0.8.7, 0.8.5) rdoc (2.5.8) thor (0.13.6) } $LOAD_PATH Sunday, November 6, 11
  24. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br rsrails$ gem list *** LOCAL GEMS

    *** bundler (0.9.25) rake (0.8.7, 0.8.5) rdoc (2.5.8) thor (0.13.6) } Filesystem Sunday, November 6, 11
  25. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br rsrails$ gem list *** LOCAL GEMS

    *** bundler (0.9.25) rake (0.8.7, 0.8.5) rdoc (2.5.8) thor (0.13.6) } Filesystem # Gemfile - Bundler gem “rake”, “0.8.5” } Gemfile Sunday, November 6, 11
  26. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br rsrails$ gem list *** LOCAL GEMS

    *** bundler (0.9.25) rake (0.8.7, 0.8.5) rdoc (2.5.8) thor (0.13.6) } Filesystem # Gemfile - Bundler gem “rake”, “0.8.5” } Gemfile rake-0.8.5 } $LOAD_PATH Sunday, November 6, 11
  27. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br # Gemfile gem "rake" rsrails$ gem

    list rake (0.8.7, 0.8.5) thor (0.13.6) Sunday, November 6, 11
  28. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br # Gemfile gem "rake" # test_load_path_lock.rb

    require "rubygems" require "bundler" Bundler.setup require "rake" require "thor" rsrails$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) Sunday, November 6, 11
  29. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br # Gemfile gem "rake" # test_load_path_lock.rb

    require "rubygems" require "bundler" Bundler.setup require "rake" require "thor" rsrails$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) Lock no $LOAD_PATH Sunday, November 6, 11
  30. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br # Gemfile gem "rake" # test_load_path_lock.rb

    require "rubygems" require "bundler" Bundler.setup require "rake" require "thor" rsrails$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) rsrails$ 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 Sunday, November 6, 11
  31. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br # Gemfile gem "rake" # test_load_path_lock.rb

    require "rubygems" require "bundler" Bundler.setup require "rake" require "thor" rsrails$ gem list rake (0.8.7, 0.8.5) thor (0.13.6) rsrails$ 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 Sunday, November 6, 11
  32. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rotas root Rails 2.3 Rails 3

    map.root :controller => "welcome" root :to => "welcome#index" Sunday, November 6, 11
  33. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rotas comuns Rails 2.3 Rails 3

    map.connect "products/:id", :controller=> "catalog", :action => "view" match 'products/:id' => 'catalog#view' Sunday, November 6, 11
  34. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rotas nomeadas Rails 2.3 Rails 3

    map.purchase "products/:id/purchase", :controller => "catalog", :action => "purchase" match "products/:id/purchase" => 'catalog#purchase', :as => :purchase Sunday, November 6, 11
  35. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 get :sold, :on => :collection end Sunday, November 6, 11
  36. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Router e Rack FTW! match "posts/:echo",

    :to => "posts#show" match "posts/:echo", :to => PostsController.action(:show) Rack App! Sunday, November 6, 11
  37. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Router e Rack FTW! match "posts/:echo",

    :to => "posts#show" match "posts/:echo", :to => PostsController.action(:show) match "/posts/:echo" => redirect("/foo/%{echo}") Rack App! Sunday, November 6, 11
  38. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Router e Rack FTW! match "posts/:echo",

    :to => "posts#show" match "posts/:echo", :to => PostsController.action(:show) match "posts/:echo" => lambda { |env| [ 200, {“Content-Type” => “plain/text”}, ["Echo!"] ] } match "/posts/:echo" => redirect("/foo/%{echo}") Rack App! Sunday, November 6, 11
  39. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Router e Rack FTW! match "posts/:echo",

    :to => "posts#show" match "posts/:echo", :to => PostsController.action(:show) match "posts/:echo" => MySinatraBlog match "posts/:echo" => lambda { |env| [ 200, {“Content-Type” => “plain/text”}, ["Echo!"] ] } match "/posts/:echo" => redirect("/foo/%{echo}") Rack App! Sunday, November 6, 11
  40. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ActionMailer rsrails$ ls -lp app/ controllers/

    helpers/ mailers/ models/ views/ rsrails$ 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 Sunday, November 6, 11
  41. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ActionMailer rsrails$ ls -lp app/ controllers/

    helpers/ mailers/ models/ views/ rsrails$ 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 Sunday, November 6, 11
  42. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 end end ActionMailer nova API Sunday, November 6, 11
  43. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 end end ActionMailer nova API Defaults Sunday, November 6, 11
  44. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 end end Variáveis de instância ActionMailer nova API Defaults Sunday, November 6, 11
  45. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 end end Variáveis de instância Attachments tipo cookies ActionMailer nova API Defaults Sunday, November 6, 11
  46. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 end end Variáveis de instância Attachments tipo cookies mail tipo respond_to do |format| ActionMailer nova API Defaults Sunday, November 6, 11
  47. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br • Google Summer of Code 2009:

    • Extrair a lógica comum entre ActiveRecord e ActiveResource ActiveModel Sunday, November 6, 11
  48. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br • Google Summer of Code 2009:

    • Extrair a lógica comum entre ActiveRecord e ActiveResource • Hoje ActiveModel Sunday, November 6, 11
  49. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br • Google Summer of Code 2009:

    • Extrair a lógica comum entre ActiveRecord e ActiveResource • Hoje • Desempenha papel no agnosticismo de ORM ActiveModel Sunday, November 6, 11
  50. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br • 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 ActiveModel Sunday, November 6, 11
  51. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 Sunday, November 6, 11
  52. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ActiveRecord::Base + ActiveModel Base.class_eval do ...

    extend ActiveModel::Naming ... include ActiveModel::Conversion include Validations ... include ActiveModel::MassAssignmentSecurity include Callbacks, ActiveModel::Observing, Timestamp end end Sunday, November 6, 11
  53. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br MyApp + ActiveModel class Person include

    ActiveModel::Validations attr_accessor :name, :age validates_presence_of :name, :age end >> p = Person.new => #<Person:0x102623588> >> p.valid? => false >> p.errors.full_messages => ["Name can't be blank", "Age can't be blank"] Sunday, November 6, 11
  54. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ActiveModel Rails::Railtie Agnosticismo de ORM Agnosticismo

    de ORM Provê uma API para que o ActionPack possa conversar com o ORM Sunday, November 6, 11
  55. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ActiveModel Rails::Railtie Agnosticismo de ORM Agnosticismo

    de ORM Integração do ORM com o Rails Provê uma API para que o ActionPack possa conversar com o ORM Sunday, November 6, 11
  56. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br module ActiveModel module Lint module Tests

    def test_to_key; end def test_to_param; end def test_valid?; end def test_persisted?; end def test_model_naming; end def test_errors_aref; end def test_errors_full_messages; end end end end Sunday, November 6, 11
  57. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Nova API select where order limit

    offset from joins includes group having lock readonly Sunday, November 6, 11
  58. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Nova API Post.find(:all, :order => "published_at

    desc", :limit => 10) Rails 2.3 Rails 3 Post.order("published_at desc").limit(10) Sunday, November 6, 11
  59. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Nova API Rails 2.3 Rails 3

    Post.all(:conditions => ["published_at <= ?", Time.now], :include => :comments) Post.where("published_at <= ?", Time.now).includes(:comments) Sunday, November 6, 11
  60. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Lazy loading Job.find(:all, :conditions => {:published

    => true}) Job.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 Rails 2.3 Rails 3 Sunday, November 6, 11
  61. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Lazy loading # 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 %> Sunday, November 6, 11
  62. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Lazy loading # 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 %> Não realiza query no DB Sunday, November 6, 11
  63. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Lazy loading # 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 %> Só aqui que será feito a query no DB Não realiza query no DB Sunday, November 6, 11
  64. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Lazy loading # 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 %> Só aqui que será feito a query no DB Não realiza query no DB Se estiver cacheado, a query não é disparada! Sunday, November 6, 11
  65. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Chainability: it “quacks” like named_scope 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) Sunday, November 6, 11
  66. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Chainability: it “quacks” like named_scope 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 Sunday, November 6, 11
  67. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Chainability: it “quacks” like named_scope 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 Sunday, November 6, 11
  68. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Falando em named_scope... class Post <

    ActiveRecord::Base has_many :comments scope :published, where('posts.published_at is not null') scope :recent, published.order("posts.published_at desc").limit(10) end class Comment < ActiveRecord::Base belongs_to :post scope :from_published_posts, joins(:post) & Post.published end Sunday, November 6, 11
  69. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Falando em named_scope... class Post <

    ActiveRecord::Base has_many :comments scope :published, where('posts.published_at is not null') scope :recent, published.order("posts.published_at desc").limit(10) end class Comment < ActiveRecord::Base belongs_to :post scope :from_published_posts, joins(:post) & Post.published end Sunday, November 6, 11
  70. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Falando em named_scope... class Post <

    ActiveRecord::Base has_many :comments scope :published, where('posts.published_at is not null') scope :recent, published.order("posts.published_at desc").limit(10) end class Comment < ActiveRecord::Base belongs_to :post scope :from_published_posts, joins(:post) & Post.published end Sunday, November 6, 11
  71. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Falando em named_scope... class Post <

    ActiveRecord::Base has_many :comments scope :published, where('posts.published_at is not null') scope :recent, published.order("posts.published_at desc").limit(10) end class Comment < ActiveRecord::Base belongs_to :post scope :from_published_posts, joins(:post) & Post.published end Sunday, November 6, 11
  72. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Falando em named_scope... class Post <

    ActiveRecord::Base has_many :comments scope :published, where('posts.published_at is not null') scope :recent, published.order("posts.published_at desc").limit(10) end class Comment < ActiveRecord::Base belongs_to :post scope :from_published_posts, joins(:post) & Post.published end DRY Sunday, November 6, 11
  73. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br def index @users = User.all respond_to

    do |format| format.html # index.html.erb format.xml { render :xml => @users } end end Rails 2.3 Sunday, November 6, 11
  74. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br def index @users = User.all respond_to

    do |format| format.html # index.html.erb format.xml { render :xml => @users } end end Rails 2.3 Sunday, November 6, 11
  75. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rails 3.0 respond_to :html, :xml def

    index @users = User.all respond_with(@users) end Sunday, November 6, 11
  76. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rails 3.0 respond_to :html, :xml def

    index @users = User.all respond_with(@users) end Sunday, November 6, 11
  77. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 Rails 2.3 Sunday, November 6, 11
  78. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Rails 3.0 def create @user =

    User.new(params[:user]) flash[:notice] = 'User was successfully created' if @user.save respond_with(@user) end Sunday, November 6, 11
  79. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br github.com/plataformatec/responders FlashResponder: seta o flash baseado

    no controller, na action e no status do recurso HttpCacheResponder: adiciona o cabeçalho HTTP Last-Modified para requests de API Sunday, November 6, 11
  80. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br github.com/plataformatec/responders FlashResponder: seta o flash baseado

    no controller, na action e no status do recurso HttpCacheResponder: adiciona o cabeçalho HTTP Last-Modified para requests de API CollectionResponder: altera o redirecionamento para a action :index ao criar/atualizar um recurso Sunday, November 6, 11
  81. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br remote_form_for(@post) Unobtrusive Javascript: Rails 2.3 link_to

    'Destroy', post, :confirm => 'Are you sure?',:method => :delete Sunday, November 6, 11
  82. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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 Sunday, November 6, 11
  83. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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> Sunday, November 6, 11
  84. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Unobtrusive Javascript: Rails 3 form_for(@posts, :remote

    => true) <form action="/posts" class="new_post" data-remote="true" id="new_post" method="post"> Sunday, November 6, 11
  85. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Unobtrusive Javascript: Rails 3 form_for(@posts, :remote

    => true) <form action="/posts" class="new_post" data-remote="true" id="new_post" method="post"> Sunday, November 6, 11
  86. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Unobtrusive Javascript: 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> Sunday, November 6, 11
  87. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Unobtrusive Javascript: 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> Sunday, November 6, 11
  88. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br 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! Sunday, November 6, 11
  89. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br HTML 5 custom data attributes JS

    driver para cada framework Agnosticismo de Javascript Javascript no Rails 3 Sunday, November 6, 11
  90. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br • link_to_remote • observe_field • form_remote_tag

    • submit_to_remote • periodically_call_remote • remote_form_for • observe_form • button_to_remote Helpers Deprecados no Rails 3 http://github.com/rails/prototype_legacy_helper Sunday, November 6, 11
  91. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br XSS protection <%= @job.title %> <%=

    h @job.title %> Rails 2.3: unsafe por default safe unsafe <%= @job.title %> <%= raw @job.title %> Rails 3: safe por default safe unsafe Sunday, November 6, 11
  92. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br XSS protection <%= @job.title %> <%=

    h @job.title %> Rails 2.3: unsafe por default safe unsafe <%= @job.title %> <%= raw @job.title %> Rails 3: safe por default safe unsafe Sunday, November 6, 11
  93. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br XSS protection <%= @job.title %> <%=

    h @job.title %> Rails 2.3: unsafe por default safe unsafe <%= @job.title %> <%= raw @job.title %> Rails 3: safe por default safe unsafe Sunday, November 6, 11
  94. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Helpers que retornam HTML module ApplicationHelper

    def strong(content) "<strong>#{h content}</strong>".html_safe end end Sunday, November 6, 11
  95. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Helpers que retornam HTML module ApplicationHelper

    def strong(content) "<strong>#{h content}</strong>".html_safe end end Dicas: 1. Certificar-se de que todo input está sendo escapado Sunday, November 6, 11
  96. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Helpers que retornam HTML module ApplicationHelper

    def strong(content) "<strong>#{h content}</strong>".html_safe end end Dicas: 1. Certificar-se de que todo input está sendo escapado 2. Chamar html_safe no output Sunday, November 6, 11
  97. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Agora... como eu começo a usar

    tudo isso que está disponível no Rails 3? Sunday, November 6, 11
  98. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Para começar rsrails$ gem install rails

    --pre ... Successfully installed rails-3.0.0.rc 23 gems installed rsrails$ rails -v Rails 3.0.0.rc Sunday, November 6, 11
  99. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Para atualizar • rails upgrade plugin:

    • http://github.com/rails/rails_upgrade Sunday, November 6, 11
  100. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Para atualizar • rails upgrade plugin:

    • http://github.com/rails/rails_upgrade • rails upgrade handbook: • http://www.railsupgradehandbook.com/ Sunday, November 6, 11
  101. Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Para atualizar • rails upgrade plugin:

    • http://github.com/rails/rails_upgrade • rails upgrade handbook: • http://www.railsupgradehandbook.com/ • screencasts “Upgrading to Rails 3”: • http://railscasts.com/, Episódios #225, #226 e #227 Sunday, November 6, 11