TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
rails3 @ rsonrails - 2010.08.21
1. Rails 3
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
2. Rails 3
ID blog twitter
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
3. Quem sou eu?
• Carlos Antonio da Silva
• Desenvolvedor Ruby e Rails há mais de 2 anos
• Engenheiro da Plataforma Tecnologia a 1 ano
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
4. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
5. Desenvolvimento de
aplicações em Rails
Coaching em Consultoria
Rails e Agile
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
6. Rails 3
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
7. Como tudo começou?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
8. Como tudo começou?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
9. Como tudo começou?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
10. Como tudo começou?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
11. Como tudo começou?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
12. Como tudo começou?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
13. Vantagens do Rails 3
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
14. Vantagens do Rails 3
Performance
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
15. Vantagens do Rails 3
Modularidade
Performance
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
16. Vantagens do Rails 3
Agnosticismo
Modularidade
Performance
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
17. Arquitetura
Rails
ActionDispatch
ActiveSupport
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
18. Arquitetura
Todo o resto são
Railties!
Rails
ActionDispatch
ActiveSupport
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
19. Arquitetura
Todo o resto são
Railties!
ActiveRecord
Rails
ActionView
ActionDispatch
outros... ActiveSupport
ActionController
ActionMailer
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
20. Como o Rails 3
muda o modo como
desenvolvemos?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
21. rails command
Rails 2.3 Rails 3
rails blog rails new blog
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
22. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
23. rails command
Rails 3 Shortcuts!
rails server rails s
rails console rails c
rails generate rails g
rails dbconsole rails db
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
24. blog/config.ru
require ::File.expand_path('../config/environment', __FILE__)
run Blog::Application
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
25. blog/config.ru
require ::File.expand_path('../config/environment', __FILE__)
run Blog::Application
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
26. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
27. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
28. O que é uma Rack App?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
29. 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!"] ] }
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
30. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
31. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
32. 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)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
33. 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)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
34. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
35. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
36. Biblioteca para gerenciamento de
dependências
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
39. Rubygems
Resolução de dependências
Gems instaladas do rack: require "rubygems"
* rack (1.0.1) require "thin"
* rack (1.1.0) gem "actionpack", "2.3.5"
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
40. Rubygems
Resolução de dependências
Gems instaladas do rack: require "rubygems"
* rack (1.0.1) require "thin"
* rack (1.1.0) gem "actionpack", "2.3.5"
BOOM!!!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
41. Rubygems
Resolução de dependências
Gems instaladas do rack: require "rubygems"
* rack (1.0.1) require "thin"
* rack (1.1.0) 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)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
42. Rubygems
Resolução de dependências
Gems instaladas do rack: require "rubygems"
* rack (1.0.1) require "thin"
* rack (1.1.0) 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)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
43. Rubygems
Resolução de dependências
Gems instaladas do rack: require "rubygems"
* rack (1.0.1) require "thin"
* rack (1.1.0) 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)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
44. Bundler: Gemfile
# Gemfile
gem "thin"
gem "actionpack", "2.3.5"
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
45. 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)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
46. 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)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
47. Rubygems
$LOAD_PATH
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
48. }
rsrails$ gem list
*** LOCAL GEMS ***
bundler (0.9.25)
rake (0.8.7, 0.8.5)
Filesystem
rdoc (2.5.8)
thor (0.13.6)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
49. }
rsrails$ gem list
*** LOCAL GEMS ***
bundler (0.9.25)
rake (0.8.7, 0.8.5)
Filesystem
rdoc (2.5.8)
thor (0.13.6)
# Rubygems
gem “rake”, “0.8.5”
} Gemfile
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
50. }
rsrails$ gem list
*** LOCAL GEMS ***
bundler (0.9.25)
rake (0.8.7, 0.8.5)
Filesystem
rdoc (2.5.8)
thor (0.13.6)
# Rubygems
gem “rake”, “0.8.5”
} Gemfile
}
bundler (0.9.25)
rake (0.8.7, 0.8.5) $LOAD_PATH
rdoc (2.5.8)
thor (0.13.6)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
51. Bundler
Lock no $LOAD_PATH
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
52. Esqueci de colocar no config.gem!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
53. Esqueci de colocar no config.gem!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
54. }
rsrails$ gem list
*** LOCAL GEMS ***
bundler (0.9.25)
rake (0.8.7, 0.8.5)
Filesystem
rdoc (2.5.8)
thor (0.13.6)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
55. }
rsrails$ 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 - Bundler
gem “rake”, “0.8.5”
} Gemfile
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
56. }
rsrails$ 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 - Bundler
gem “rake”, “0.8.5”
} Gemfile
rake-0.8.5
} $LOAD_PATH
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
57. rsrails$ gem list
rake (0.8.7, 0.8.5)
thor (0.13.6)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
58. rsrails$ gem list
rake (0.8.7, 0.8.5)
thor (0.13.6)
# Gemfile
gem "rake"
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
59. rsrails$ 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"
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
60. rsrails$ 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"
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
61. rsrails$ 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"
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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
62. rsrails$ 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"
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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
63. Packaging System
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
64. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
65. Router
Nova API
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
66. Rotas root
Rails 2.3
map.root :controller => "welcome"
Rails 3
root :to => "welcome#index"
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
67. Rotas comuns
Rails 2.3
map.connect "products/:id", :controller=> "catalog", :action => "view"
Rails 3
match 'products/:id' => 'catalog#view'
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
68. Rotas nomeadas
Rails 2.3
map.purchase "products/:id/purchase", :controller => "catalog",
:action => "purchase"
Rails 3
match "products/:id/purchase" => 'catalog#purchase',
:as => :purchase
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
69. Resources com member e
collection
Rails 2.3
map.resources :products, :member => { :short => :get,
:toggle => :post }, :collection => { :sold => :get }
Rails 3 resources :products do
member do
get :short
post :toggle
end
get :sold, :on => :collection
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
70. Router e Rack FTW!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
71. Router e Rack FTW!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
72. Router e Rack FTW!
match "posts/:echo", :to => "posts#show"
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
73. Router e Rack FTW!
match "posts/:echo", :to => "posts#show"
Rack App!
match "posts/:echo", :to => PostsController.action(:show)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
74. Router e Rack FTW!
match "posts/:echo", :to => "posts#show"
match "posts/:echo", :to => PostsController.action(:show)
Rack App!
match "/posts/:echo" => redirect("/foo/%{echo}")
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
75. 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!
match "posts/:echo" => lambda { |env| [ 200, {“Content-Type” =>
“plain/text”}, ["Echo!"] ] }
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
76. Router e Rack FTW!
match "posts/:echo", :to => "posts#show"
match "posts/:echo", :to => PostsController.action(:show)
match "/posts/:echo" => redirect("/foo/%{echo}")
match "posts/:echo" => lambda { |env| [ 200, {“Content-Type” =>
“plain/text”}, ["Echo!"] ] }
Rack App!
match "posts/:echo" => MySinatraBlog
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
77. 100% compatível
com Rack
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
78. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
79. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
80. ActionMailer
rsrails$ ls -lp app/
controllers/
helpers/
mailers com diretório próprio
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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
81. ActionMailer
Nova API
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
82. TMail
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
83. TMail
Mail
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
84. ActionMailer nova 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
85. ActionMailer nova API
class Notifier < ActionMailer::Base Defaults
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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
86. ActionMailer nova API
class Notifier < ActionMailer::Base Defaults
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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
87. ActionMailer nova API
class Notifier < ActionMailer::Base Defaults
Variáveis default :from => "system@example.com"
de
instância def signup_notification(recipient) Attachments tipo
@account = recipient cookies
attachments['image.jpg'] = File.read("image.jpg")
mail(:to => recipient.email) do |format|
format.html
format.text
end
end
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
88. ActionMailer nova API
class Notifier < ActionMailer::Base Defaults
Variáveis default :from => "system@example.com"
de
instância def signup_notification(recipient) Attachments tipo
@account = recipient cookies
attachments['image.jpg'] = File.read("image.jpg")
mail(:to => recipient.email) do |format|
format.html
format.text
end
end mail tipo respond_to do |format|
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
89. AbstractController::Base
ActionController::Metal
ActionMailer::Base ActionController::Base
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
90. Menos coisas para
lembrar
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
91. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
92. ActiveModel
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
93. ActiveModel
• Google Summer of Code 2009:
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
94. ActiveModel
• Google Summer of Code 2009:
• Extrair a lógica comum entre ActiveRecord e
ActiveResource
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
95. ActiveModel
• Google Summer of Code 2009:
• Extrair a lógica comum entre ActiveRecord e
ActiveResource
• Hoje
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
96. ActiveModel
• Google Summer of Code 2009:
• Extrair a lógica comum entre ActiveRecord e
ActiveResource
• Hoje
• Desempenha papel no agnosticismo de ORM
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
97. ActiveModel
• Google Summer of Code 2009:
• Extrair a lógica comum entre ActiveRecord e
ActiveResource
• Hoje
• Desempenha papel no agnosticismo de ORM
• Permite a criação de models à la ActiveRecord
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
98. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
99. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
100. 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"]
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
101. Agnosticismo de ORM
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
102. Agnosticismo de ORM
Agnosticismo de ORM
ActiveModel Rails::Railtie
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
103. Agnosticismo de ORM
Agnosticismo de ORM
ActiveModel Rails::Railtie
Provê uma API para que o
ActionPack possa conversar com o
ORM
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
104. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
105. ActiveModel
Validations
Callbacks
Serialization
ActiveRecord Data Mapper MongoDB MeuModel
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
106. ActiveModel::Lint::Tests
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
107. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
108. ActiveRecord-like
Ótimo exemplo de uso do ActiveModel
http://github.com/plataformatec/mail_form
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
109. Menos hacks!
Reusabilidade
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
110. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
111. Nova API
select joins
where includes
order group
limit having
offset lock
from readonly
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
112. Nova API
Rails 2.3
Post.find(:all, :order => "published_at desc", :limit => 10)
Rails 3
Post.order("published_at desc").limit(10)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
113. Nova API
Rails 2.3
Post.all(:conditions => ["published_at <= ?", Time.now],
:include => :comments)
Rails 3
Post.where("published_at <= ?", Time.now).includes(:comments)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
114. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
115. 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 %>
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
116. Lazy loading
# 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 %>
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
117. Lazy loading
# 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
118. Lazy loading
# 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 %>
Se estiver cacheado, a query
<% @jobs.each do |job| %>
não é disparada!
...
<% end %>
<% end %>
Só aqui que será feito a query no DB
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
119. 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)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
120. Chainability:
it “quacks” like named_scope
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)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
121. Chainability:
it “quacks” like named_scope
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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
122. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
123. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
124. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
125. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
126. 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 DRY
belongs_to :post
scope :from_published_posts, joins(:post) & Post.published
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
127. Mas e sobre o ARel
que tanto se fala?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
128. ARel == Relational Algebra
ARel != ActiveRecord::Relation
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
129. Código mais limpo
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
130. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
131. Rails 2.3
def index
@users = User.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @users }
end
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
132. Rails 2.3
def index
@users = User.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @users }
end
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
133. Rails 3.0
respond_to :html, :xml
def index
@users = User.all
respond_with(@users)
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
134. Rails 3.0
respond_to :html, :xml
def index
@users = User.all
respond_with(@users)
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
135. 3 variáveis
Formato do request
Verbo HTTP
Status do recurso
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
136. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
137. Rails 3.0
def create
@user = User.new(params[:user])
flash[:notice] = 'User was successfully created' if @user.save
respond_with(@user)
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
138. respond_with(@users)
ActionController::Responder
Formato do request
Verbo HTTP
Status do recurso
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
139. respond_with(@users)
ActionController::Responder
to_code
Formato do request
Verbo HTTP
Status do recurso
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
140. Responders Customizados
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
142. github.com/plataformatec/responders
FlashResponder: seta o flash baseado no controller,
na action e no status do recurso
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
143. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
144. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
145. DRY
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
146. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
147. Unobtrusive Javascript: Rails 2.3
remote_form_for(@post)
link_to 'Destroy', post, :confirm => 'Are you sure?',:method => :delete
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
148. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
149. 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>
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
150. Unobtrusive Javascript: Rails 3
form_for(@posts, :remote => true)
<form action="/posts" class="new_post" data-remote="true" id="new_post"
method="post">
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
151. Unobtrusive Javascript: Rails 3
form_for(@posts, :remote => true)
<form action="/posts" class="new_post" data-remote="true" id="new_post"
method="post">
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
152. 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>
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
153. 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>
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
154. 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!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
155. Javascript no Rails 3
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
156. Javascript no Rails 3
Agnosticismo de Javascript
HTML 5 custom data attributes JS driver para cada framework
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
157. Helpers Deprecados no Rails 3
• link_to_remote
• observe_field
• form_remote_tag
• submit_to_remote
• periodically_call_remote
• remote_form_for
• observe_form
• button_to_remote
http://github.com/rails/prototype_legacy_helper
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
158. Agnosticismo +
HTML 5
OMG! JQUERY!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
159. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
160. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
161. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
162. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
163. Helpers que retornam HTML
module ApplicationHelper
def strong(content)
"<strong>#{h content}</strong>".html_safe
end
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
164. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
165. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
166. Segurança
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
167. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
168. Agora... como eu começo
a usar tudo isso que está
disponível no Rails 3?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
169. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
170. Para atualizar
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
171. Para atualizar
• rails upgrade plugin:
• http://github.com/rails/rails_upgrade
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
172. Para atualizar
• rails upgrade plugin:
• http://github.com/rails/rails_upgrade
• rails upgrade handbook:
• http://www.railsupgradehandbook.com/
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
173. 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
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
174. ?! Tem muito mais aqui!
http://github.com/plataformatec
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11
175. ?! Tem muito mais aqui!
http://github.com/plataformatec
ID blog twitter
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Sunday, November 6, 11