Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Rails 3
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
blog twitterID
Rails 3
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.brSunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Desenvolvimento deaplicações em Rails
ConsultoriaCoaching em Rails e Agile
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Rails 3
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Como tudo começou?
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Como tudo começou?
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Como tudo começou?
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Como tudo começou?
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Como tudo começou?
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Como tudo começou?
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Vantagens do Rails 3
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Vantagens do Rails 3
Performance
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Vantagens do Rails 3
Performance
Modularidade
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Vantagens do Rails 3
Performance
Modularidade
Agnosticismo
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Arquitetura
ActionDispatch
ActiveSupport
Rails
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Arquitetura
ActionDispatch
ActiveSupport
Rails
Todo o resto são Railties!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Arquitetura
ActionDispatch
ActiveSupport
Rails
Todo o resto são Railties!
ActiveRecord
ActionMailer
ActionController
ActionView
outros...
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Como o Rails 3 muda o modo como
desenvolvemos?
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
rails commandRails 2.3 Rails 3
rails blog rails new blog
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
rails command
ruby script/serverruby script/consoleruby script/generateruby script/dbconsole
rails consolerails generaterails dbconsole
rails server
Rails 2.3 Rails 3
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
rails command
rails serverrails consolerails generaterails dbconsole
rails crails grails db
rails s
Rails 3 Shortcuts!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
blog/config.ru
require ::File.expand_path('../config/environment', __FILE__)run Blog::Application
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
blog/config.ru
require ::File.expand_path('../config/environment', __FILE__)run Blog::Application
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
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
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
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!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
O que é uma Rack App?
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
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!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
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
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
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)
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
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)
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
BundlerRouterActionMailerActiveModelActiveRecordRespondersUnobtrusive JavascriptXSS Protection
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.brSunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Biblioteca para gerenciamento de dependências
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 thinGem thin-1.2.7 daemons (>= 1.0.9, runtime) eventmachine (>= 0.12.6, runtime) rack (>= 1.0.0, runtime)
RubygemsResolução de dependências
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 thinGem thin-1.2.7 daemons (>= 1.0.9, runtime) eventmachine (>= 0.12.6, runtime) rack (>= 1.0.0, runtime)
RubygemsResolução de dependências
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
RubygemsResoluçã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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
RubygemsResoluçã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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
RubygemsResoluçã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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
RubygemsResoluçã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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
RubygemsResoluçã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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Bundler : Gemfile# Gemfilegem "thin"gem "actionpack", "2.3.5"
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Bundler : Gemfile# Gemfilegem "thin"gem "actionpack", "2.3.5"
rsrails$ 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)
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Bundler : Gemfile# Gemfilegem "thin"gem "actionpack", "2.3.5"
rsrails$ 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)
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Rubygems
$LOAD_PATH
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
# Rubygemsgem “rake”, “0.8.5” } Gemfile
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
# Rubygemsgem “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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Bundler
Lock no $LOAD_PATH
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Esqueci de colocar no config.gem!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Esqueci de colocar no config.gem!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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 - Bundlergem “rake”, “0.8.5” } Gemfile
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 - Bundlergem “rake”, “0.8.5” } Gemfile
rake-0.8.5 } $LOAD_PATH
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
rsrails$ gem listrake (0.8.7, 0.8.5)thor (0.13.6)
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
# Gemfilegem "rake"
rsrails$ gem listrake (0.8.7, 0.8.5)thor (0.13.6)
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
# Gemfilegem "rake"
# test_load_path_lock.rbrequire "rubygems"require "bundler"Bundler.setuprequire "rake"require "thor"
rsrails$ gem listrake (0.8.7, 0.8.5)thor (0.13.6)
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
# Gemfilegem "rake"
# test_load_path_lock.rbrequire "rubygems"require "bundler"Bundler.setuprequire "rake"require "thor"
rsrails$ gem listrake (0.8.7, 0.8.5)thor (0.13.6)
Lock no $LOAD_PATH
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
# Gemfilegem "rake"
# test_load_path_lock.rbrequire "rubygems"require "bundler"Bundler.setuprequire "rake"require "thor"
rsrails$ gem listrake (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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
# Gemfilegem "rake"
# test_load_path_lock.rbrequire "rubygems"require "bundler"Bundler.setuprequire "rake"require "thor"
rsrails$ gem listrake (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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Packaging SystemOMG!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
BundlerRouterActionMailerActiveModelActiveRecordRespondersUnobtrusive JavascriptXSS Protection
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Nova API
Router
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Rotas rootRails 2.3
Rails 3
map.root :controller => "welcome"
root :to => "welcome#index"
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Rotas comunsRails 2.3
Rails 3
map.connect "products/:id", :controller=> "catalog", :action => "view"
match 'products/:id' => 'catalog#view'
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Rotas nomeadasRails 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
Carlos Antonio @cantoniodasilvablog.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 => :collectionend
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Router e Rack FTW!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Router e Rack FTW!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Router e Rack FTW!
match "posts/:echo", :to => "posts#show"
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
100% compatível com Rack
OMG!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
BundlerRouterActionMailerActiveModelActiveRecordRespondersUnobtrusive JavascriptXSS Protection
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
ActionMailer
Nova API
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
TMail
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
TMail
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 endend
ActionMailer nova API
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 endend
ActionMailer nova API
Defaults
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 endend
Variáveisde
instância
ActionMailer nova API
Defaults
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 endend
Variáveisde
instância Attachments tipo cookies
ActionMailer nova API
Defaults
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 endend
Variáveisde
instância Attachments tipo cookies
mail tipo respond_to do |format|
ActionMailer nova API
Defaults
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
ActionMailer ::Base ActionController ::Base
ActionController ::Metal
AbstractController ::Base
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Menos coisas para lembrar
OMG!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
BundlerRouterActionMailerActiveModelActiveRecordRespondersUnobtrusive JavascriptXSS Protection
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
ActiveModel
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
• Google Summer of Code 2009:
ActiveModel
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
• Google Summer of Code 2009:
• Extrair a lógica comum entre ActiveRecord e ActiveResource
ActiveModel
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
• Google Summer of Code 2009:
• Extrair a lógica comum entre ActiveRecord e ActiveResource
• Hoje
ActiveModel
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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 endend
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 endend
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
MyApp + ActiveModel
class Person include ActiveModel::Validations attr_accessor :name, :age validates_presence_of :name, :ageend
>> 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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Agnosticismo de ORM
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
ActiveModel Rails::Railtie
Agnosticismo de ORM
Agnosticismo de ORM
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
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
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Callbacks
Serialization
Validations
Data Mapper MongoDBActiveRecord MeuModel
ActiveModel
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
ActiveModel::Lint::Tests
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 endend
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
ActiveRecord-like
http://github.com/plataformatec/mail_form
Ótimo exemplo de uso do ActiveModel
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Menos hacks! Reusabilidade
OMG!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
BundlerRouterActionMailerActiveModelActiveRecordRespondersUnobtrusive JavascriptXSS Protection
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Nova API
selectwhereorderlimitoffsetfrom
joinsincludesgrouphavinglockreadonly
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Nova APIRails 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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Lazy loading# 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 %>
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Lazy loading# 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
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Lazy loading# 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
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Lazy loading# 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, a query não é disparada!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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.publishedend
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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.publishedend
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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.publishedend
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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.publishedend
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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.publishedend
DRY
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Mas e sobre o ARel que tanto se fala?
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
ARel == Relational Algebra
ARel != ActiveRecord::Relation
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Código mais limpoOMG!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
BundlerRouterActionMailerActiveModelActiveRecordRespondersUnobtrusive JavascriptXSS Protection
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
def index @users = User.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @users } endend
Rails 2.3
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
def index @users = User.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @users } endend
Rails 2.3
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Rails 3.0
respond_to :html, :xml
def index @users = User.all respond_with(@users)end
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Rails 3.0
respond_to :html, :xml
def index @users = User.all respond_with(@users)end
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
3 variáveis
Formato do request
Verbo HTTP
Status do recurso
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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 endend
Rails 2.3
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
respond_with(@users)
ActionController ::Responder
Formato do request
Verbo HTTP
Status do recurso
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
respond_with(@users)
ActionController ::Responder
to_code
Formato do request
Verbo HTTP
Status do recurso
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Responders Customizados
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
github.com/plataformatec/responders
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
github.com/plataformatec/responders
FlashResponder: seta o flash baseado no controller, na action e no status do recurso
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
DRYOMG!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
BundlerRouterActionMailerActiveModelActiveRecordRespondersUnobtrusive JavascriptXSS Protection
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Javascript no Rails 3
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
HTML 5 custom data attributes JS driver para cada framework
Agnosticismo de Javascript
Javascript no Rails 3
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Agnosticismo + HTML 5
OMG! JQUERY!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
BundlerRouterActionMailerActiveModelActiveRecordRespondersUnobtrusive JavascriptXSS Protection
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
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
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
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
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
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
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Helpers que retornam HTML
module ApplicationHelper def strong(content) "<strong>#{h content}</strong>".html_safe endend
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Helpers que retornam HTML
module ApplicationHelper def strong(content) "<strong>#{h content}</strong>".html_safe endend
Dicas:1. Certificar-se de que todo input está sendo escapado
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Helpers que retornam HTML
module ApplicationHelper def strong(content) "<strong>#{h content}</strong>".html_safe endend
Dicas:1. Certificar-se de que todo input está sendo escapado2. Chamar html_safe no output
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
SegurançaOMG!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
BundlerRouterActionMailerActiveModelActiveRecordRespondersUnobtrusive JavascriptXSS Protection
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Agora... como eu começo a usar tudo isso que está
disponível no Rails 3?
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Para começar
rsrails$ gem install rails --pre
...Successfully installed rails-3.0.0.rc23 gems installed
rsrails$ rails -vRails 3.0.0.rc
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Para atualizar
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
Para atualizar
• rails upgrade plugin:
• http://github.com/rails/rails_upgrade
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.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
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
http://github.com/plataformatec
Tem muito mais aqui!?!
Sunday, November 6, 11
Carlos Antonio @cantoniodasilvablog.plataformatec.com.br
blog twitterID
http://github.com/plataformatec
Tem muito mais aqui!?!
Sunday, November 6, 11