Carlos Antonio apresenta sobre o framework Rails 3, destacando suas principais vantagens como melhorias de performance e modularidade, além de descrever como o Rails 3 muda a forma de desenvolvimento com a adoção do padrão Rack e do gerenciador de dependências Bundler.
2. Rails 3
ID blog twitter
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
4. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
5. Desenvolvimento de
aplicações em Rails
Coaching em Consultoria
Rails e Agile
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
13. Vantagens do Rails 3
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
14. Vantagens do Rails 3
Performance
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
15. Vantagens do Rails 3
Modularidade
Performance
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
16. Vantagens do Rails 3
Agnosticismo
Modularidade
Performance
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
17. Arquitetura
Rails
ActionDispatch
ActiveSupport
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
18. Arquitetura
Todo o resto são
Railties!
Rails
ActionDispatch
ActiveSupport
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
19. Arquitetura
Todo o resto são
Railties!
ActiveRecord
Rails
ActionView
ActionDispatch
outros... ActiveSupport
ActionController
ActionMailer
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
20. Como o Rails 3
muda o modo como
desenvolvemos?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
21. rails command
Rails 2.3 Rails 3
rails blog rails new blog
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
24. blog/config.ru
require ::File.expand_path('../config/environment', __FILE__)
run Blog::Application
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
25. blog/config.ru
require ::File.expand_path('../config/environment', __FILE__)
run Blog::Application
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
28. O que é uma Rack App?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
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
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
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
34. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
35. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
51. Bundler
Lock no $LOAD_PATH
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
52. Esqueci de colocar no config.gem!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
53. Esqueci de colocar no config.gem!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
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
57. rsrails$ gem list
rake (0.8.7, 0.8.5)
thor (0.13.6)
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
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
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
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
63. Packaging System
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
64. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
65. Router
Nova API
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
66. Rotas root
Rails 2.3
map.root :controller => "welcome"
Rails 3
root :to => "welcome#index"
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
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
70. Router e Rack FTW!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
71. Router e Rack FTW!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
72. Router e Rack FTW!
match "posts/:echo", :to => "posts#show"
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
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
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
77. 100% compatível
com Rack
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
78. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
81. ActionMailer
Nova API
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
83. TMail
Mail
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
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
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
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
89. AbstractController::Base
ActionController::Metal
ActionMailer::Base ActionController::Base
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
90. Menos coisas para
lembrar
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
91. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
93. ActiveModel
• Google Summer of Code 2009:
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
94. ActiveModel
• Google Summer of Code 2009:
• Extrair a lógica comum entre ActiveRecord e
ActiveResource
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
95. ActiveModel
• Google Summer of Code 2009:
• Extrair a lógica comum entre ActiveRecord e
ActiveResource
• Hoje
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
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
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
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
102. Agnosticismo de ORM
Agnosticismo de ORM
ActiveModel Rails::Railtie
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
105. ActiveModel
Validations
Callbacks
Serialization
ActiveRecord Data Mapper MongoDB MeuModel
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
108. ActiveRecord-like
Ótimo exemplo de uso do ActiveModel
http://github.com/plataformatec/mail_form
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
109. Menos hacks!
Reusabilidade
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
110. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
111. Nova API
select joins
where includes
order group
limit having
offset lock
from readonly
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
127. Mas e sobre o ARel
que tanto se fala?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
128. ARel == Relational Algebra
ARel != ActiveRecord::Relation
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
129. Código mais limpo
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
130. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
133. Rails 3.0
respond_to :html, :xml
def index
@users = User.all
respond_with(@users)
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
134. Rails 3.0
respond_to :html, :xml
def index
@users = User.all
respond_with(@users)
end
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
135. 3 variáveis
Formato do request
Verbo HTTP
Status do recurso
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
138. respond_with(@users)
ActionController::Responder
Formato do request
Verbo HTTP
Status do recurso
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
139. respond_with(@users)
ActionController::Responder
to_code
Formato do request
Verbo HTTP
Status do recurso
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
145. DRY
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
146. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
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
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
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
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
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
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
155. Javascript no Rails 3
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
158. Agnosticismo +
HTML 5
OMG! JQUERY!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
159. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
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
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
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
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
166. Segurança
OMG!
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
167. Bundler
Router
ActionMailer
ActiveModel
ActiveRecord
Responders
Unobtrusive Javascript
XSS Protection
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
168. Agora... como eu começo
a usar tudo isso que está
disponível no Rails 3?
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
171. Para atualizar
• rails upgrade plugin:
• http://github.com/rails/rails_upgrade
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
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
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
174. ?! Tem muito mais aqui!
http://github.com/plataformatec
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
175. ?! Tem muito mais aqui!
http://github.com/plataformatec
ID blog twitter
Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
Notes de l'éditeur
- Vamos falar sobre Rails 3
* Arquitetura, vantagens, novidades, APIs e muito mais
- Essa palestra &#xE9; mais focada para desenvolvedores que conhecem Rails 2.3
- Vamos falar sobre Rails 3
* Arquitetura, vantagens, novidades, APIs e muito mais
- Essa palestra &#xE9; mais focada para desenvolvedores que conhecem Rails 2.3
- Vamos falar sobre Rails 3
* Arquitetura, vantagens, novidades, APIs e muito mais
- Essa palestra &#xE9; mais focada para desenvolvedores que conhecem Rails 2.3
Antes de tudo, quem sou eu?
O que &#xE9; a Plataforma?
- Fundada no come&#xE7;o de 2009
- Projetos open source bem conhecidos: Devise
- Rails Core: Jos&#xE9; Valim
- Gostamos trabalhar sempre procurando o melhor modo de se fazer as coisas
O que &#xE9; a Plataforma?
- Fundada no come&#xE7;o de 2009
- Projetos open source bem conhecidos: Devise
- Rails Core: Jos&#xE9; Valim
- Gostamos trabalhar sempre procurando o melhor modo de se fazer as coisas
O que &#xE9; a Plataforma?
- Fundada no come&#xE7;o de 2009
- Projetos open source bem conhecidos: Devise
- Rails Core: Jos&#xE9; Valim
- Gostamos trabalhar sempre procurando o melhor modo de se fazer as coisas
- Vamos falar sobre Rails 3
* Arquitetura, vantagens, novidades, APIs e muito mais
- Essa palestra &#xE9; mais focada para desenvolvedores que conhecem Rails 2.3
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
- Performance: Yehuda Katkz, Merb
- Agn&#xF3;stico a ORM, Javascript, template Engine
- Modularidade: posso aproveitar hooks em v&#xE1;rios pontos e trocar m&#xF3;dulos &#x201C;internos&#x201D; do Rails pelos meus pr&#xF3;prios
- Performance: Yehuda Katkz, Merb
- Agn&#xF3;stico a ORM, Javascript, template Engine
- Modularidade: posso aproveitar hooks em v&#xE1;rios pontos e trocar m&#xF3;dulos &#x201C;internos&#x201D; do Rails pelos meus pr&#xF3;prios
- Performance: Yehuda Katkz, Merb
- Agn&#xF3;stico a ORM, Javascript, template Engine
- Modularidade: posso aproveitar hooks em v&#xE1;rios pontos e trocar m&#xF3;dulos &#x201C;internos&#x201D; do Rails pelos meus pr&#xF3;prios
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
* Rails fornece a estrutura do railties
- Rails == Rails::Railtie + Rails::Engine + Rails::Application + Processo de Boot + Rails::Generators + Rake Tasks + Command (server, console)
* ActionDispatch: rack on stereoids!
* objetos request e respone
* roteamento
* v&#xE1;rios middlewares
- Digamos que come&#xE7;amos nossa aplica&#xE7;&#xE3;o e vamos inici&#xE1;la
- Quem conhece rack, percebeu que minha aplica&#xE7;&#xE3;o agora &#xE9; uma Rack App mesmo, posso at&#xE9; chamar com rackup
- Vamos ver onde est&#xE1; definido essa minha rack app Blog::Application
- Blogo::Application herda de RailsApplication
- Rails::Application cuida de toda processo de boot da minha aplica&#xE7;&#xE3;o: executar Railties, plugins e engines
- Vamos dar uma olhada nesse arquivo que est&#xE1; sendo feito require
- Blogo::Application herda de RailsApplication
- Rails::Application cuida de toda processo de boot da minha aplica&#xE7;&#xE3;o: executar Railties, plugins e engines
- Vamos dar uma olhada nesse arquivo que est&#xE1; sendo feito require
- Blogo::Application herda de RailsApplication
- Rails::Application cuida de toda processo de boot da minha aplica&#xE7;&#xE3;o: executar Railties, plugins e engines
- Vamos dar uma olhada nesse arquivo que est&#xE1; sendo feito require
- Blogo::Application herda de RailsApplication
- Rails::Application cuida de toda processo de boot da minha aplica&#xE7;&#xE3;o: executar Railties, plugins e engines
- Vamos dar uma olhada nesse arquivo que est&#xE1; sendo feito require
- Blogo::Application herda de RailsApplication
- Rails::Application cuida de toda processo de boot da minha aplica&#xE7;&#xE3;o: executar Railties, plugins e engines
- Vamos dar uma olhada nesse arquivo que est&#xE1; sendo feito require
- Blogo::Application herda de RailsApplication
- Rails::Application cuida de toda processo de boot da minha aplica&#xE7;&#xE3;o: executar Railties, plugins e engines
- Vamos dar uma olhada nesse arquivo que est&#xE1; sendo feito require
- O arquivo boot.rb tem como responsabilidade basicamente carregar as gems que minha aplica&#xE7;&#xE3;o depende
- Agnostico a gerenciador de pacotes
- Em uma linha, isso &#xE9; o que Bundler &#xE9;, mas ele n&#xE3;o &#xE9; s&#xF3; isso. O bundler resolve dois problemas muito importantes:
- Resolu&#xE7;&#xE3;o de depend&#xEA;ncias
- Lock no $LOAD_PATH
- Em uma linha, isso &#xE9; o que Bundler &#xE9;, mas ele n&#xE3;o &#xE9; s&#xF3; isso. O bundler resolve dois problemas muito importantes:
- Resolu&#xE7;&#xE3;o de depend&#xEA;ncias
- Lock no $LOAD_PATH
- Em uma linha, isso &#xE9; o que Bundler &#xE9;, mas ele n&#xE3;o &#xE9; s&#xF3; isso. O bundler resolve dois problemas muito importantes:
- Resolu&#xE7;&#xE3;o de depend&#xEA;ncias
- Lock no $LOAD_PATH
- Imagine que nossa aplica&#xE7;&#xE3;o dependa de duas gems, actionpack e do thin. O nosso gerenciador de pacotes precisa resolver qual vers&#xE3;o de cada gem e de suas depend&#xEA;ncias ele ir&#xE1; usar.
- O thin depende de rack 1.0.x
- O actionpack depende de qualquer versao do rack maior que 1.0.0
- O que acontece quando fazemos require das duas?
- Rubygems resolve as depend&#xEA;ncias de modo &#x201C;procedural&#x201D;
- O thin depende de rack 1.0.x
- O actionpack depende de qualquer versao do rack maior que 1.0.0
- O que acontece quando fazemos require das duas?
- Rubygems resolve as depend&#xEA;ncias de modo &#x201C;procedural&#x201D;
- O thin depende de rack 1.0.x
- O actionpack depende de qualquer versao do rack maior que 1.0.0
- O que acontece quando fazemos require das duas?
- Rubygems resolve as depend&#xEA;ncias de modo &#x201C;procedural&#x201D;
- O thin depende de rack 1.0.x
- O actionpack depende de qualquer versao do rack maior que 1.0.0
- O que acontece quando fazemos require das duas?
- Rubygems resolve as depend&#xEA;ncias de modo &#x201C;procedural&#x201D;
- O thin depende de rack 1.0.x
- O actionpack depende de qualquer versao do rack maior que 1.0.0
- O que acontece quando fazemos require das duas?
- Rubygems resolve as depend&#xEA;ncias de modo &#x201C;procedural&#x201D;
- Com o bundler, &#xE9; diferente. Ele analisa todas as gems e suas depend&#xEA;ncias necess&#xE1;rias, e calcula quais vers&#xF5;es que atendem os requisitos do conjunto de gems
- Com o bundler, &#xE9; diferente. Ele analisa todas as gems e suas depend&#xEA;ncias necess&#xE1;rias, e calcula quais vers&#xF5;es que atendem os requisitos do conjunto de gems
Que problema &#xE9; esse do lock no $LOAD_PATH?
Mas como que esse lock no $LOAD_PATH nos ajuda?
Mas como que esse lock no $LOAD_PATH nos ajuda?
Que problema &#xE9; esse do lock no $LOAD_PATH?
- Lembra dessa frase? O Bundler resolveu esse problema para voc&#xEA;!
Mas como que esse lock no $LOAD_PATH nos ajuda?
Mas como que esse lock no $LOAD_PATH nos ajuda?
- It feels like a the controller API
- It talks like the controller API
- Hey, maybe this is the controller API!
- It feels like a the controller API
- It talks like the controller API
- Hey, maybe this is the controller API!
- It feels like a the controller API
- It talks like the controller API
- Hey, maybe this is the controller API!
- It feels like a the controller API
- It talks like the controller API
- Hey, maybe this is the controller API!
- Railtie: integra&#xE7;&#xE3;o com Rails, tais como: rakes, config, generators, middleware, log, initializers
- ActiveModel::Lint::Tests
- Railtie: integra&#xE7;&#xE3;o com Rails, tais como: rakes, config, generators, middleware, log, initializers
- ActiveModel::Lint::Tests
- Railtie: integra&#xE7;&#xE3;o com Rails, tais como: rakes, config, generators, middleware, log, initializers
- ActiveModel::Lint::Tests
- Railtie: integra&#xE7;&#xE3;o com Rails, tais como: rakes, config, generators, middleware, log, initializers
- ActiveModel::Lint::Tests
- Railtie: integra&#xE7;&#xE3;o com Rails, tais como: rakes, config, generators, middleware, log, initializers
- ActiveModel::Lint::Tests
- Falar oq &#xE9; o mail_form: formul&#xE1;rio de contato
- Podemos pensar no ActiveRecord::Relation como um named_scope an&#xF4;nimo
- Query feita just-in-time
- Query feita just-in-time
- Query feita just-in-time
- Os novos finders s&#xE3;o encade&#xE1;veis
- Os novos finders s&#xE3;o encade&#xE1;veis
- Os novos finders s&#xE3;o encade&#xE1;veis
- Os novos finders s&#xE3;o encade&#xE1;veis
- Os novos finders s&#xE3;o encade&#xE1;veis
- Os novos finders s&#xE3;o encade&#xE1;veis
- Muitas de nossas actions tem o c&#xF3;digo de respond_to repetido v&#xE1;rias vezes.
- Responder &#xE9; uma solu&#xE7;&#xE3;o do Rails para encapsular esse tipo de c&#xF3;digo e seguir o DRY
- Vamos ver como ele funciona. Temos as vari&#xE1;veis do format, e do verbo http
- Imagine agora a action create, no Rails 2.3
Com o responders, ficaria assim. Conseguimos deletar muito c&#xF3;digo!
- o ActionController::Responder nada mais &#xE9; do que a implementa&#xE7;&#xE3;o dessa tabela
- Uma coisa interessante, &#xE9; que podemos criar nossos pr&#xF3;prios responders
Oq &#xE9; javascript n&#xE3;o obtrusivo? Primeiro, vamos ver oq n&#xE3;o &#xE9;.
Oq &#xE9; javascript n&#xE3;o obtrusivo? Primeiro, vamos ver oq n&#xE3;o &#xE9;.
- Drivers para os principais frameworks
- Se n&#xE3;o tiver o que vc quer, vc sempre pode fazer o seu!
- Pudemos ver ent&#xE3;o qual a funda&#xE7;&#xE3;o para o agnosticismo de JS do Rails 3
- Pudemos ver ent&#xE3;o qual a funda&#xE7;&#xE3;o para o agnosticismo de JS do Rails 3
- Pudemos ver ent&#xE3;o qual a funda&#xE7;&#xE3;o para o agnosticismo de JS do Rails 3
- &#xC9; importante notar algumas dicas na hora de construir um helper que retorna HTML.
- &#xC9; importante notar algumas dicas na hora de construir um helper que retorna HTML.
- &#xC9; importante notar algumas dicas na hora de construir um helper que retorna HTML.
- &#xC9; importante notar algumas dicas na hora de construir um helper que retorna HTML.
- &#xC9; importante notar algumas dicas na hora de construir um helper que retorna HTML.
- Nosso blog, twitter e contato
- Estaremos o dia inteiro aqui no evento, nos procure para conversarmos
- Nosso blog, twitter e contato
- Estaremos o dia inteiro aqui no evento, nos procure para conversarmos
- Nosso blog, twitter e contato
- Estaremos o dia inteiro aqui no evento, nos procure para conversarmos