Transcript
Page 1: And the Greatest of These Is ... Space

And the Greatest of These Is... Rack SupportBen Scofield – Viget Labs

Saturday, July 25, 2009

Page 2: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 3: And the Greatest of These Is ... Space

Application TemplatesSaturday, July 25, 2009

Page 4: And the Greatest of These Is ... Space

Nested Attribute Assignmentflickr: angelrays

Saturday, July 25, 2009

Page 5: And the Greatest of These Is ... Space

ActiveRecord::Base#touchflickr: jjjohn

Saturday, July 25, 2009

Page 6: And the Greatest of These Is ... Space

DB Seedingflickr: richardthomas78

Saturday, July 25, 2009

Page 7: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 8: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 9: And the Greatest of These Is ... Space

Rack

Saturday, July 25, 2009

Page 10: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 11: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 12: And the Greatest of These Is ... Space

def call(env) [ status, # 200 headers, # {"Content-Type" => "text/html"} body # ["<html>...</html>"] ]end

Saturday, July 25, 2009

Page 13: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 14: And the Greatest of These Is ... Space

requestapplication

responseSaturday, July 25, 2009

Page 15: And the Greatest of These Is ... Space

requestapplication

response

middleware

middleware

Saturday, July 25, 2009

Page 16: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 17: And the Greatest of These Is ... Space

Rack::Profilerflickr: oberazzi

Saturday, July 25, 2009

Page 18: And the Greatest of These Is ... Space

Rack::MailExceptionsflickr: warmnfuzzy

Saturday, July 25, 2009

Page 19: And the Greatest of These Is ... Space

Rack::Cacheflickr: timpatterson

Saturday, July 25, 2009

Page 20: And the Greatest of These Is ... Space

rack::cascade

Rack::Cascadeflickr: _at

Saturday, July 25, 2009

Page 21: And the Greatest of These Is ... Space

Rack in Rails

Saturday, July 25, 2009

Page 22: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 23: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 24: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 25: And the Greatest of These Is ... Space

> rake middlewareuse Rack::Lockuse ActionDispatch::ShowExceptions, [true]use ActionDispatch::Callbacks, [true]use ActionDispatch::Rescue, [#<Method: ...>]use ActionDispatch::Session::CookieStore, [{...}]use ActionDispatch::ParamsParseruse Rack::MethodOverrideuse Rack::Headuse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacherun ActionController::Dispatcher.new

Saturday, July 25, 2009

Page 26: And the Greatest of These Is ... Space

> rake middlewareuse Rack::Lockuse ActionDispatch::ShowExceptions, [true]use ActionDispatch::Callbacks, [true]use ActionDispatch::Rescue, [#<Method: ...>]use ActionDispatch::Session::CookieStore, [{...}]use ActionDispatch::ParamsParseruse Rack::MethodOverrideuse Rack::Headuse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacherun ActionController::Dispatcher.new

> rake middlewareuse Rack::Lockuse ActionDispatch::ShowExceptions, [true]use ActionDispatch::Callbacks, [true]use ActionDispatch::Rescue, [#<Method: ...>]use ActionDispatch::Session::CookieStore, [{...}]use ActionDispatch::ParamsParseruse Rack::MethodOverrideuse Rack::Headuse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacherun ActionController::Dispatcher.new

Saturday, July 25, 2009

Page 27: And the Greatest of These Is ... Space

app = Rack::Builder.new { use Rails::Rack::LogTailer unless options[:detach] use Rails::Rack::Debugger if options[:debugger]

map "/" do use Rails::Rack::Static run ActionController::Dispatcher.new end}.to_app

Saturday, July 25, 2009

Page 28: And the Greatest of These Is ... Space

Rails::Initializer.run do |config| config.middleware.insert_before Rack::Head, Ben::Asplode config.middleware.swap Rack::Lock, Ben::Lock config.middleware.use Rack::MailExceptionsend

Saturday, July 25, 2009

Page 29: And the Greatest of These Is ... Space

Rails::Initializer.run do |config| config.middleware.insert_before Rack::Head, Ben::Asplode config.middleware.swap Rack::Lock, Ben::Lock config.middleware.use Rack::MailExceptionsend

# in config/initializers/middlewares.rb

ActionController::Dispatcher.middleware.insert_before 'Rack::Head', AppenderActionController::Dispatcher.middleware.delete 'Rack::Lock'ActionController::Dispatcher.middleware.use Prepender

Saturday, July 25, 2009

Page 30: And the Greatest of These Is ... Space

Metalflickr: lrargerich

Saturday, July 25, 2009

Page 31: And the Greatest of These Is ... Space

http://www.kiwibean.com/

Saturday, July 25, 2009

Page 32: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 33: And the Greatest of These Is ... Space

EXPAND: testing metalPLEASE STAND BYTHIS IS ONLY A TEST

Saturday, July 25, 2009

Page 34: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 35: And the Greatest of These Is ... Space

METAL

Sinatra

Saturday, July 25, 2009

Page 36: And the Greatest of These Is ... Space

Cool Tricks

Saturday, July 25, 2009

Page 37: And the Greatest of These Is ... Space

Rack::Bugflickr: catdancing

Saturday, July 25, 2009

Page 38: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 39: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 40: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 41: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 42: And the Greatest of These Is ... Space

requires </body>

Saturday, July 25, 2009

Page 43: And the Greatest of These Is ... Space

Progressive CachingSaturday, July 25, 2009

Page 44: And the Greatest of These Is ... Space

Progressive CachingSaturday, July 25, 2009

Page 45: And the Greatest of These Is ... Space

Progressive CachingSaturday, July 25, 2009

Page 46: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 47: And the Greatest of These Is ... Space

class SessionsController < ApplicationController def create # ... session[:personalize] = { :logged_in => true, :quicklist => current_user.quicklist.episode_ids, :subscriptions => current_user.subscription_ids } endend

Saturday, July 25, 2009

Page 48: And the Greatest of These Is ... Space

class ChannelsController < ApplicationController caches_page :show def show @channel = Channel.find(params[:id]) endend

Saturday, July 25, 2009

Page 49: And the Greatest of These Is ... Space

$(document).ready(function() { $.getJSON('/personalize', function(data) {

// identify quicklisted episodes $.each(data['quicklist'], function() { $('#episode_'+this).addClass('listed'); }); // switch navigation if (data['logged_in']) { $('#logged_in_nav').show(); } // etc. });});

Saturday, July 25, 2009

Page 50: And the Greatest of These Is ... Space

class Personalizer def self.call(env) if env["PATH_INFO"] =~ /^/personalize/ [ 200, {"Content-Type" => "application/javascript"}, env['rack.session'][:personalize].to_json ] else [404, {"Content-Type" => "text/html"}, ["Not Found"]] end endend

Saturday, July 25, 2009

Page 51: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 52: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 53: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 54: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 55: And the Greatest of These Is ... Space

standard

progressive 0.0960.039

0.617

class PullList def self.call(env) if env["PATH_INFO"] =~ /^\/pulls/ [ 200, {"Content-Type" => "application/javascript"}, [Pull.by_user(user).for_date(date).map {|i| i.item_id}.to_json]] else [404, {"Content-Type" => "text/html"}, ["Not Found"]] end endend

Saturday, July 25, 2009

Page 56: And the Greatest of These Is ... Space

class PullList def self.call(env) if env["PATH_INFO"] =~ /^\/pulls/ [ 200, {"Content-Type" => "application/javascript"}, [env['rack.session'][:pulls].to_json] ] else [404, {"Content-Type" => "text/html"}, ["Not Found"]] end endend

standard

progressive

progressive v2 0.023

0.096

0.043

0.039

0.617

Saturday, July 25, 2009

Page 57: And the Greatest of These Is ... Space

DIY

Saturday, July 25, 2009

Page 58: And the Greatest of These Is ... Space

requestapplication

response

middleware

middleware

Saturday, July 25, 2009

Page 59: And the Greatest of These Is ... Space

Rack::EmbiggenerSaturday, July 25, 2009

Page 60: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 61: And the Greatest of These Is ... Space

class Embiggener < Test::Unit::TestCase def test_embiggener_should_embiggen_known_url body = ["Hello! I'm at http://bit.ly/31IqMl"] assert_equal ["Hello! I'm at http://cnn.com"], Rack:: Embiggener.embiggen_urls(body) end

def test_embiggener_should_embiggen_multiple_urls body = [ "Hello! I'm at http://bit.ly/31IqMl", "And I'm at http://bit.ly/31IqMl" ] assert_equal [ "Hello! I'm at http://cnn.com", "And I'm at http://cnn.com" ], Rack::Embiggener.embiggen_urls(body) endend

Saturday, July 25, 2009

Page 62: And the Greatest of These Is ... Space

module Rack class Embiggener def self.embiggen_urls(original_body, login, key) new_body = [] original_body.each { |line| bits = line.scan(/(http:\/\/bit\.ly\/(.{6}))/)

new_body << bits.uniq.inject(line) do |body, bit| original_bit, hash = *bit new_url = embiggened_url(hash, login, key) body.gsub(original_bit, new_url) if new_url end } new_body end

# ... endend

Saturday, July 25, 2009

Page 63: And the Greatest of These Is ... Space

module Rack class Embiggener # ...

def self.embiggened_url(hash, login, key) url = [ "http://api.bit.ly/expand?version=2.0.1", "shortUrl=http://bit.ly/#{hash}", "login=#{login}", "apiKey=#{key}" ].join('&') response = JSON.parse(Net::HTTP.get_response(URI.parse(url))) if response['statusCode'] = 'OK' embiggened_url = response['results'][hash]['longUrl'] end end

# ... endend

Saturday, July 25, 2009

Page 64: And the Greatest of These Is ... Space

module Rack class Embiggener # ... attr_accessor :api_login, :api_key def initialize(app, api_login, api_key) @app = app @api_login = api_login @api_key = api_key end

def call(env) status, headers, body = @app.call(env) headers.delete('Content-Length') response = Rack::Response.new( Rack::Embiggener.embiggen_urls(body, api_login, api_hash), status, headers ) response.finish return response.to_a end endend

Saturday, July 25, 2009

Page 65: And the Greatest of These Is ... Space

module Rack class Embiggener def self.embiggen_urls(original_body, login, key) new_body = [] original_body.each { |line| bits = line.scan(/bit\:(\w+?)/)

new_body << bits.uniq.inject(line) do |body, bit| hash = bit.first original_bit = "bit:#{hash}" new_url = embiggened_url(hash, login, key) body.gsub(original_bit, new_url) if new_url end } new_body

end # ... endend

Saturday, July 25, 2009

Page 66: And the Greatest of These Is ... Space

module Rack class Embiggener # ...

def self.embiggened_url(hash, login, key) url = [ "http://api.bit.ly/expand?version=2.0.1", "hash=#{hash}", "login=#{login}", "apiKey=#{key}" ].join('&') response = JSON.parse(Net::HTTP.get_response(URI.parse(url))) if response['statusCode'] = 'OK' embiggened_url = response['results'][hash]['longUrl'] end end

# ... endend

Saturday, July 25, 2009

Page 67: And the Greatest of These Is ... Space

WARNINGexception handling

Saturday, July 25, 2009

Page 68: And the Greatest of These Is ... Space

WARNINGexception handling

formerly:

Saturday, July 25, 2009

Page 69: And the Greatest of These Is ... Space

Rack::Hoptoad** unofficial; thoughtbot is not responsible for this middleware; do not taunt rack::hoptoad; pregnant women should consult their doctors before using rack::hoptoad

Saturday, July 25, 2009

Page 70: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 71: And the Greatest of These Is ... Space

> rake middlewareuse Rack::Lockuse ActionDispatch::ShowExceptions, [true]use ActionDispatch::Callbacks, [true]use ActionDispatch::Rescue, [#<Method: ...>]use ActionDispatch::Session::CookieStore, [{...}]use ActionDispatch::ParamsParseruse Rack::MethodOverrideuse Rack::Headuse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacherun ActionController::Dispatcher.new

Saturday, July 25, 2009

Page 72: And the Greatest of These Is ... Space

ActionController::Dispatcher.middleware.delete ActionDispatch::ShowExceptionsActionController::Dispatcher.middleware.delete ActionDispatch::Rescue ActionController::Dispatcher.middleware.use 'Rack::Hoptoad', 'my-api-key'ActionController::Dispatcher.middleware.use 'Rack::ShowExceptions'

Saturday, July 25, 2009

Page 73: And the Greatest of These Is ... Space

module Rack class Hoptoad def initialize(app, api_key) @app = app @api_key = api_key end

def call(env) @app.call(env) rescue => exception notify_hoptoad(exception, env) raise exception end

# ... endend

Saturday, July 25, 2009

Page 74: And the Greatest of These Is ... Space

module Rack class Hoptoad def notify_hoptoad(exception, env) headers = { 'Content-type' => 'application/x-yaml', 'Accept' => 'text/xml, application/xml' } url = URI.parse("http://hoptoadapp.com/notices")

http = Net::HTTP.new(url.host, url.port)

data = { :api_key => @api_key, :error_message => "#{exception.class}: #{exception}", :backtrace => exception.backtrace, :request => {}, :session => env['rack.session'], :environment => env }

response = http.post( url.path, stringify_keys(:notice => data).to_yaml, headers ) if response != Net::HTTPSuccess # Hoptoad post failed end end endend

Saturday, July 25, 2009

Page 75: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 76: And the Greatest of These Is ... Space

Intangibles

Saturday, July 25, 2009

Page 77: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 78: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 79: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 80: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 81: And the Greatest of These Is ... Space

Saturday, July 25, 2009

Page 82: And the Greatest of These Is ... Space

Thank You

ben scofield - @bscofield - http://www.viget.com/extend - http://www.speakerrate.com/bscofield

Saturday, July 25, 2009


Recommended