53. # GET /weblog
# GET /weblog.xml
# GET /weblog.rss
class WeblogController < ActionController::Base
def index
@posts = Post.find :all
respond_to do |format|
format.html
format.xml { render :xml => @posts.to_xml }
format.rss { render :action => "feed.rxml" }
end
end
end
Tuesday, December 15, 2009
58. class TrafficLight
include AlterEgo
state :proceed, :default => true do
handle :color { "green" }
transition :to => :caution, :on => :cycle!
end
state :caution do
handle :color { "yellow" }
transition :to => :stop, :on => :cycle!
end
state :stop do
handle :color { "red" }
transition :to => :proceed, :on => :cycle!
end
end
Tuesday, December 15, 2009
59. light = TrafficLight.new
light.color # => "green"
light.cycle!
light.color # => "yellow"
light.cycle!
light.color # => "red"
light.cycle!
light.color # => "green"
• Acts As State Machine (AASM)
• Alter Ego
• State-Fu
http://jmettraux.wordpress.com/2009/07/03/state-machine-workflow-engine/
Tuesday, December 15, 2009
63. # config/initializers/mime_types.rb
Mime.register_alias "text/html", :iphone
# app/controllers/application.rb
class ApplicationController < ActionController::Base
before_filter :adjust_format_for_iphone
private
def adjust_format_for_iphone
if request.env["HTTP_USER_AGENT"] &&
request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/]
request.format = :iphone
end
end
end
Tuesday, December 15, 2009
64. # config/initializers/mime_types.rb
Mime.register_alias "text/html", :iphone
# app/controllers/application.rb
class ApplicationController < ActionController::Base
before_filter :adjust_format_for_iphone
private
def adjust_format_for_iphone
if request.env["HTTP_USER_AGENT"] &&
request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/]
request.format = :iphone
end
end
end
Tuesday, December 15, 2009
65. # config/initializers/mime_types.rb
Mime.register_alias "text/html", :iphone
# app/controllers/application.rb
class ApplicationController < ActionController::Base
before_filter :adjust_format_for_iphone
private
def adjust_format_for_iphone
if request.env["HTTP_USER_AGENT"] &&
request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/]
request.format = :iphone
end
end
end
Tuesday, December 15, 2009
66. # app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
respond_to do |format|
format.html # renders index.html.erb
format.iphone # renders index.iphone.erb
end
end
end
Tuesday, December 15, 2009
67. # app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
respond_to do |format|
format.html # renders index.html.erb
format.iphone # renders index.iphone.erb
end
end
end
Tuesday, December 15, 2009
68. class PostsController < ApplicationController
before_filter :authenticate, :except => [ :index ]
def index
render :text => "Everyone can see me!"
end
def edit
render :text => "I’m not publicly accessible"
end
private
def authenticate
authenticate_or_request_with_http_basic do |user_name,
password|
user_name == "dhh" && password == "secret"
end
end
end
Tuesday, December 15, 2009
69. class PostsController < ApplicationController
before_filter :authenticate, :except => [ :index ]
def index
render :text => "Everyone can see me!"
end
def edit
render :text => "I’m not publicly accessible"
end
private
def authenticate
authenticate_or_request_with_http_basic do |user_name,
password|
user_name == "dhh" && password == "secret"
end
end
end
Tuesday, December 15, 2009
70. class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
# See ActionController::RequestForgeryProtection for
# details
# Uncomment the :secret if you're not using the
# cookie session store
protect_from_forgery # :secret =>
# '9b76dcad7de4d8eca67e9d53329006ac'
end
Tuesday, December 15, 2009
71. class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
# See ActionController::RequestForgeryProtection for
# details
# Uncomment the :secret if you're not using the
# cookie session store
protect_from_forgery # :secret =>
# '9b76dcad7de4d8eca67e9d53329006ac'
end
Tuesday, December 15, 2009
72. class PostsController < ApplicationController
rescue_from User::NotAuthorized, :with => :deny_access
protected
def deny_access
...
end
end
Tuesday, December 15, 2009
73. class PostsController < ApplicationController
rescue_from User::NotAuthorized, :with => :deny_access
protected
def deny_access
...
end
end
Tuesday, December 15, 2009
74. # Your secret key for verifying cookie session data
# integrity. If you change this key, all old sessions
# will become invalid! Make sure the secret is at least
# 30 characters and all random, no regular words or you'll
# be exposed to dictionary attacks.
config.action_controller.session = {
:session_key => '_my_app_session',
:secret =>
'ec54b1c89c810d5937ede6b2969ee227c7653ffaffb37927a71203ef968
7928d256572ae5c8e66efbf0b9686103b597c3bae537b813fc838580c794
248c428da'
}
Tuesday, December 15, 2009
75. create_table :people do |t|
t.column, "account_id", :integer
t.column, "first_name", :string, :null => false
t.column, "last_name", :string, :null => false
t.column, "description", :text
t.column, "created_at", :datetime
t.column, "updated_at", :datetime
end
create_table :people do |t|
t.integer :account_id
t.string :first_name, :last_name, :null => false
t.text :description
t.timestamps
end
Tuesday, December 15, 2009
76. # sellers.yml
shopify:
name: Shopify
# products.yml
pimp_cup:
seller: shopify
name: Pimp cup
Tuesday, December 15, 2009
95. class ArticlesController < ApplicationController
def show_with_respond_to_block
@article = Article.find(params[:id])
# unless stale? => "304 Not Modified"
if stale?(:last_modified => @article.published_at.utc,
:etag => @article)
respond_to do |wants|
# normal response processing
end
end
end
def show_with_implied_render
@article = Article.find(params[:id])
# If fresh => "304 Not Modified"
fresh_when(:last_modified => @article.published_at.utc,
:etag => @article)
end
end
Tuesday, December 15, 2009
96. class ArticlesController < ApplicationController
def show_with_respond_to_block
@article = Article.find(params[:id])
# unless stale? => "304 Not Modified"
if stale?(:last_modified => @article.published_at.utc,
:etag => @article)
respond_to do |wants|
# normal response processing
end
end
end
def show_with_implied_render
@article = Article.find(params[:id])
# If fresh => "304 Not Modified"
fresh_when(:last_modified => @article.published_at.utc,
:etag => @article)
end
end
Tuesday, December 15, 2009
97. class ArticlesController < ApplicationController
def show_with_respond_to_block
@article = Article.find(params[:id])
# unless stale? => "304 Not Modified"
if stale?(:last_modified => @article.published_at.utc,
:etag => @article)
respond_to do |wants|
# normal response processing
end
end
end
def show_with_implied_render
@article = Article.find(params[:id])
# If fresh => "304 Not Modified"
fresh_when(:last_modified => @article.published_at.utc,
:etag => @article)
end
end
Tuesday, December 15, 2009
98. # config/environments/production.rb:
config.threadsafe!
# config/database.yml
development:
adapter: mysql
username: root
database: myapp_dev
pool: 10
Tuesday, December 15, 2009
99. # config/routes.rb
map.resources :publishers, :shallow => true do |publisher|
publisher.resources :magazines do |magazine|
magazine.resources :photos
end
end
# /publishers/1 ==> publisher_path(1)
# /publishers/1/magazines ==> publisher_magazines_path(1)
# /magazines/2 ==> magazine_path(2)
# /magazines/2/photos ==> magazines_photos_path(2)
# /photos/3 ==> photo_path(3)
Tuesday, December 15, 2009
100. # antes
def full_name
@full_name ||= "#{first_name} #{last_name}"
end
# depois
extend ActiveSupport::Memoizable
def full_name
"#{first_name} #{last_name}"
end
memoize :full_name
Tuesday, December 15, 2009
101. class Vendor < ActiveRecord::Base
has_one :account
delegate :email, :password, :to => :account,
:prefix => true
end
# @vendor.account_email
# @vendor.account_password
class Vendor < ActiveRecord::Base
has_one :account
delegate :email, :password, :to => :account,
:prefix => :owner
end
# @vendor.owner_email
# @vendor.owner_password
Tuesday, December 15, 2009
102. class UserMailer < ActionMailer::Base
def registration(user)
subject "You've registered"
from "system@example.com"
end
end
# layouts/user_mailer.html.erb
class UserMailer < ActionMailer::Base
layout 'email'
...
end
# layouts/email.html.erb
Tuesday, December 15, 2009
109. > rake middleware
use Rack::Lock
use ActionController::Failsafe
use ActionController::Session::CookieStore
use ActionController::ParamsParser
use Rack::MethodOverride
use Rack::Head
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
run ActionController::Dispatcher.new
Tuesday, December 15, 2009
110. # app/metal/poller.rb
class Poller < Rails::Rack::Metal
def call(env)
if env["PATH_INFO"] =~ /^/poller/
[200, {"Content-Type" => "text/html"}, "Hello, World!"]
else
[404, {"Content-Type" => "text/html"}, "Not Found"]
end
end
end
# app/controllers/old_poller_controller.rb
class OldPollerController < ApplicationController
def poller
render :text => "Hello World!"
end
end
Tuesday, December 15, 2009
111. # benchmark the traditional controller
$ ab -n 1000 http://127.0.0.1:3000/old_poller/poller
Requests per second: 408.45 [#/sec] (mean)
Time per request: 2.448 [ms] (mean)
# benchmark the Metal middleware
$ ab -n 1000 http://127.0.0.1:3000/poller
Requests per second: 1154.66 [#/sec] (mean)
Time per request: 0.866 [ms] (mean)
Tuesday, December 15, 2009
114. class Project < ActiveRecord::Base
after_update :save_tasks
validates_associated :tasks
def new_task_attributes=(task_attributes)
task_attributes.each { |attr| tasks.build(attr) }
end
def existing_task_attributes=(task_attributes)
tasks.reject(&:new_record?).each do |task|
attributes = task_attributes[task.id.to_s]
if attributes['_delete'] == '1'
tasks.delete(task)
else
task.attributes = attributes
end
end
end
private
def save_tasks
tasks.each { |task| task.save(false)}
end
end
Tuesday, December 15, 2009
115. class Project < ActiveRecord::Base
has_many :tasks
accept_nested_attributes_for :tasks,
:allow_destroy => true
end
Tuesday, December 15, 2009
118. User.transaction do
User.create(:username => 'Admin')
User.transaction(:requires_new => true) do
User.create(:username => 'Regular')
raise ActiveRecord::Rollback
end
end
User.find(:all) # => Returns only Admin
Tuesday, December 15, 2009
121. class Article < ActiveRecord::Base
default_scope :order => 'created_at DESC'
end
Article.find(:all)
#=> "SELECT * FROM `articles` ORDER BY created_at DESC"
class Article < ActiveRecord::Base
default_scope :order => 'created_at DESC'
named_scope :published, :conditions => { :published => true }
end
Article.published
#=> "SELECT * FROM `articles` WHERE published = true
# ORDER BY created_at DESC"
# Ignore other scoping within this block
Article.with_exclusive_scope { find(:all) }
#=> "SELECT * FROM `articles`
Tuesday, December 15, 2009
122. class Article < ActiveRecord::Base
default_scope :order => 'created_at DESC'
end
Article.find(:all)
#=> "SELECT * FROM `articles` ORDER BY created_at DESC"
class Article < ActiveRecord::Base
default_scope :order => 'created_at DESC'
named_scope :published, :conditions => { :published => true }
end
Article.published
#=> "SELECT * FROM `articles` WHERE published = true
# ORDER BY created_at DESC"
# Ignore other scoping within this block
Article.with_exclusive_scope { find(:all) }
#=> "SELECT * FROM `articles`
Tuesday, December 15, 2009
123. Article.find_each { |a| ... }
# => iterate over all articles, in chunks of 1000 (the default)
Article.find_each(:conditions => { :published => true },
:batch_size => 100 ) { |a| ... }
# iterate over published articles in chunks of 100
Article.find_in_batches do |articles|
articles.each { |a| ... }
end
# => articles is array of size 1000
Article.find_in_batches(batch_size => 100 ) do |articles|
articles.each { |a| ... }
end
# iterate over all articles in chunks of 100
Article.published.find_in_batches(:batch_size => 100 ) do |articles|
...
end
# iterate over published articles in chunks of 100
Tuesday, December 15, 2009
124. Article.find_each { |a| ... }
# => iterate over all articles, in chunks of 1000 (the default)
Article.find_each(:conditions => { :published => true },
:batch_size => 100 ) { |a| ... }
# iterate over published articles in chunks of 100
Article.find_in_batches do |articles|
articles.each { |a| ... }
end
# => articles is array of size 1000
Article.find_in_batches(batch_size => 100 ) do |articles|
articles.each { |a| ... }
end
# iterate over all articles in chunks of 100
Article.published.find_in_batches(:batch_size => 100 ) do |articles|
...
end
# iterate over published articles in chunks of 100
Tuesday, December 15, 2009
125. Article.find_each { |a| ... }
# => iterate over all articles, in chunks of 1000 (the default)
Article.find_each(:conditions => { :published => true },
:batch_size => 100 ) { |a| ... }
# iterate over published articles in chunks of 100
Article.find_in_batches do |articles|
articles.each { |a| ... }
end
# => articles is array of size 1000
Article.find_in_batches(batch_size => 100 ) do |articles|
articles.each { |a| ... }
end
# iterate over all articles in chunks of 100
Article.published.find_in_batches(:batch_size => 100 ) do |articles|
...
end
# iterate over published articles in chunks of 100
Tuesday, December 15, 2009
126. class ArticlesController < ApplicationController
before_filter :digest_authenticate
def digest_authenticate
s = authenticate_or_request_with_http_digest("Admin") do |username|
(@user = User.find_by_username(username)).try(cleartext_password)
end
# If authentication succeeds, log the user in.
# If not, kick back out a failure
# message as the response body
if s
session[:user_id] = @user.id
else
request_http_digest_authentication("Admin",
"Authentication failed")
end
end
end
Tuesday, December 15, 2009
127. class ArticlesController < ApplicationController
before_filter :digest_authenticate
def digest_authenticate
s = authenticate_or_request_with_http_digest("Admin") do |username|
(@user = User.find_by_username(username)).try(cleartext_password)
end
# If authentication succeeds, log the user in.
# If not, kick back out a failure
# message as the response body
if s
session[:user_id] = @user.id
else
request_http_digest_authentication("Admin",
"Authentication failed")
end
end
end
Tuesday, December 15, 2009
128. class ArticlesController < ApplicationController
before_filter :digest_authenticate
def digest_authenticate
s = authenticate_or_request_with_http_digest("Admin") do |username|
(@user = User.find_by_username(username)).try(cleartext_password)
end
# If authentication succeeds, log the user in.
# If not, kick back out a failure
# message as the response body
if s
session[:user_id] = @user.id
else
request_http_digest_authentication("Admin",
"Authentication failed")
end
end
end
Tuesday, December 15, 2009