Rails 3: Dashing to the Finish

171
{ Rails 3
  • date post

    12-Sep-2014
  • Category

    Technology

  • view

    14.918
  • download

    0

description

 

Transcript of Rails 3: Dashing to the Finish

Page 1: Rails 3: Dashing to the Finish

{ Rails 3

Page 2: Rails 3: Dashing to the Finish
Page 3: Rails 3: Dashing to the Finish

Overview

Page 4: Rails 3: Dashing to the Finish

Dashing to the Finish

Page 5: Rails 3: Dashing to the Finish

A Lot Like Rails 2.3

Page 6: Rails 3: Dashing to the Finish

Quick Refresher

Page 7: Rails 3: Dashing to the Finish

What Hasn’t Changed?

Page 8: Rails 3: Dashing to the Finish

MVC

Page 9: Rails 3: Dashing to the Finish

REST

Page 10: Rails 3: Dashing to the Finish

Resources

Page 11: Rails 3: Dashing to the Finish

Controllers

Page 12: Rails 3: Dashing to the Finish

Migrations

Page 13: Rails 3: Dashing to the Finish

AR Ideas

Page 14: Rails 3: Dashing to the Finish

Big User-Facing Changes

Page 15: Rails 3: Dashing to the Finish

File Structure

Page 16: Rails 3: Dashing to the Finish

con!g.ru

# This file is used by Rack-based # servers to start the application.require ::File.expand_path( '../config/environment', __FILE__)run Tutorial::Application

Page 17: Rails 3: Dashing to the Finish

con!g/boot.rb

require 'rubygems'

# Set up gems listed in the Gemfile.gemfile = File.expand_path( '../../Gemfile', __FILE__)if File.exist?(gemfile) ENV['BUNDLE_GEMFILE'] = gemfile require 'bundler' Bundler.setupend

Page 18: Rails 3: Dashing to the Finish

Gem!le

source 'http://rubygems.org'

gem 'rails', '3.0.0.beta3'gem 'sqlite3-ruby'

Page 19: Rails 3: Dashing to the Finish

con!g/environment.rb

# Load the rails applicationrequire File.expand_path( '../application', __FILE__)

# Initialize the rails applicationTutorial::Application.initialize!

Page 20: Rails 3: Dashing to the Finish

con!g/application.rb (1)

require File.expand_path( '../boot', __FILE__)

require 'rails/all'

if defined?(Bundler) Bundler.require(:default, Rails.env)end

Page 21: Rails 3: Dashing to the Finish

con!g/application.rb (2)

module Tutorial class Application < Rails::Application config.encoding = "utf-8" config.filter_parameters += [:password] endend

Page 22: Rails 3: Dashing to the Finish

environments/production.rbTutorial::Application.configure do config.cache_classes = true config.consider_all_requests_local = false config.action_controller.perform_caching = true config.action_dispatch.x_sendfile_header = "X-Sendfile" config.serve_static_assets = falseend

Page 23: Rails 3: Dashing to the Finish

initializers/session_store.rb

Rails.application. config.session_store( :cookie_store, :key => '_tutorial_session' )

Page 24: Rails 3: Dashing to the Finish

script/rails (1)#!/usr/bin/env ruby# This command will automatically # be run when you run "rails" with # Rails 3 gems installed from the # root of your application.

ENV_PATH = File.expand_path( '../../config/environment', __FILE__)

Page 25: Rails 3: Dashing to the Finish

script/rails (2)

BOOT_PATH = File.expand_path( '../../config/boot', __FILE__)

APP_PATH = File.expand_path( '../../config/application', __FILE__)

require BOOT_PATHrequire 'rails/commands'

Page 26: Rails 3: Dashing to the Finish

Recent

Page 27: Rails 3: Dashing to the Finish

Even Easier to Remove Bundler

Page 28: Rails 3: Dashing to the Finish

Removing Bundler

$ rm Gemfile

Page 29: Rails 3: Dashing to the Finish

app/mailers

$ script/rails g mailer welcome create app/mailers/welcome.rb invoke erb create app/views/welcome invoke test_unit create test/functional/welcome_test.rb

Page 30: Rails 3: Dashing to the Finish

app/layouts/application.html.erb

<!DOCTYPE html><html> <head> <title>Tutorial</title> <%= stylesheet_link_tag :all %> <%= javascript_include_tag :defaults %> <%= csrf_meta_tag %> </head> <body> <%= yield %> </body></html>

Page 31: Rails 3: Dashing to the Finish

public/javascripts/

rails.js

Page 32: Rails 3: Dashing to the Finish

github.com/rails/jquery-ujs

Page 33: Rails 3: Dashing to the Finish

db/seeds.rb

Page 34: Rails 3: Dashing to the Finish

rake db:setup

Page 35: Rails 3: Dashing to the Finish

db:createdb:schema:load

db:seed

Page 36: Rails 3: Dashing to the Finish

lib/tasks/setup.rake

task :bundle do system "bundle install"end

task :setup => ["bundle", "db:setup"]

Page 37: Rails 3: Dashing to the Finish

Rails Command

★ generate | g

★ console | c

★ server | s

★ dbconsole | db

★ application

★ destroy

★ benchmarker

★ profiler

★ plugin

★ runner

Page 38: Rails 3: Dashing to the Finish

Block Helpers

Page 39: Rails 3: Dashing to the Finish

Block Helpers (Before)

<% form_for @post do |f| %> <%= f.input_field :name %><% end %>

Page 40: Rails 3: Dashing to the Finish

Block Helpers (Before)

<% box do %> <p>Hello World!</p><% end %>

Page 41: Rails 3: Dashing to the Finish

Block Helpers (Before)

def box(&block) content = "<div class='box'>" << capture(&block) << "</div>" if block_called_from_erb? concat(content) else content endend

Page 42: Rails 3: Dashing to the Finish

Block Helpers (After)

<%= box do %> <p>Hello World!</p><% end %>

Page 43: Rails 3: Dashing to the Finish

Block Helpers (After)

def box(&block) "<div class='box'>" \ "#{capture(&block)}" \ "</div>"end

Page 44: Rails 3: Dashing to the Finish

Block Helpers (After)

def box(&block) "<div class='box'>" \ "#{capture(&block)}" \ "</div>".html_safeend

Page 45: Rails 3: Dashing to the Finish

Recent

Page 46: Rails 3: Dashing to the Finish

Tons of Fixes to XSS Safe

Page 47: Rails 3: Dashing to the Finish

Lots of XSS-Related

Changes to Your App...

Page 48: Rails 3: Dashing to the Finish

You’re Doing it Wrong

Page 49: Rails 3: Dashing to the Finish

Router

Page 50: Rails 3: Dashing to the Finish

Note: Signi!cant

Changes Ahead

Page 51: Rails 3: Dashing to the Finish

Also Note: Old Mapper

Still Available

Page 52: Rails 3: Dashing to the Finish

Matching

map.connect "posts", :controller => :posts, :action => :index

Page 53: Rails 3: Dashing to the Finish

Matching

map.connect "posts", :controller => :posts, :action => :index

match "posts" => "posts#index"

Page 54: Rails 3: Dashing to the Finish

Optional Segments

match "/posts(/page)" => "posts#index"

Page 55: Rails 3: Dashing to the Finish

Optional Dynamic Segments

match "/posts(/:id)" => "posts#index"

Page 56: Rails 3: Dashing to the Finish

Default Parameters

match "/posts(/:id)" => "posts#index", :defaults => {:id => 1}

Page 57: Rails 3: Dashing to the Finish

Default Parameters

match "/posts(/:id)" => "posts#index", :id => 1

Page 58: Rails 3: Dashing to the Finish

Named Routes

match "/posts(/:id)" => "posts#index", :id => 1, :as => "posts"

Page 59: Rails 3: Dashing to the Finish

The Root

root :to => "posts#index"

Page 60: Rails 3: Dashing to the Finish

Scopes

Page 61: Rails 3: Dashing to the Finish

Path Scope

match "/admin/posts" => "posts#index"match "/admin/users" => "users#index"

Page 62: Rails 3: Dashing to the Finish

Path Scope

match "/admin/posts" => "posts#index"match "/admin/users" => "users#index"

scope :path => "admin" do match "/posts" => "posts#index" match "/users" => "users#index"end

Page 63: Rails 3: Dashing to the Finish

Path Scope

match "/admin/posts" => "posts#index"match "/admin/users" => "users#index"

scope "admin" do match "/posts" => "posts#index" match "/users" => "users#index"end

Page 64: Rails 3: Dashing to the Finish

Module Scope

match "/posts" => "admin/posts#index"match "/users" => "admin/users#index"

Page 65: Rails 3: Dashing to the Finish

Module Scope

match "/posts" => "admin/posts#index"match "/users" => "admin/users#index"

scope :module => "admin" do match "/posts" => "posts#index" match "/users" => "users#index"end

Page 66: Rails 3: Dashing to the Finish

Both

match "admin/posts" => "admin/posts#index"match "admin/users" => "admin/users#index"

Page 67: Rails 3: Dashing to the Finish

Both

match "admin/posts" => "admin/posts#index"match "admin/users" => "admin/users#index"

namespace "admin" do match "/posts" => "posts#index" match "/users" => "users#index"end

Page 68: Rails 3: Dashing to the Finish

HTTP Methods

Page 69: Rails 3: Dashing to the Finish

Get Request

match "/posts" => "posts#index", :via => "get"

Page 70: Rails 3: Dashing to the Finish

Get Request

match "/posts" => "posts#index", :via => "get"

get "/posts" => "posts#index"

Page 71: Rails 3: Dashing to the Finish

Scoping

scope "/posts" do controller :posts do get "/" => :index endend

Page 72: Rails 3: Dashing to the Finish

Scoping

scope "/posts" do controller :posts do get "/" => :index endend

get "/posts" => "posts#index"

Page 73: Rails 3: Dashing to the Finish

Default Resource Route

controller :posts do scope "/posts" do get "/" => :index post "/" => :create get "/:id" => :show put "/:id" => :update delete "/:id" => :delete get "/new" => :new get "/:id/edit" => :edit endend

Page 74: Rails 3: Dashing to the Finish

Default Resource Routecontroller :posts do scope "/posts" do get "/" => :index, :as => :posts post "/" => :create get "/:id" => :show, :as => :post put "/:id" => :update delete "/:id" => :delete get "/new" => :new, :as => :new_post get "/:id/edit" => :edit, :as => :edit_post endend

Page 75: Rails 3: Dashing to the Finish

Constraints

Page 76: Rails 3: Dashing to the Finish

Regex Constraint

get "/:id" => "posts#index", :constraints => {:id => /\d+/}

Page 77: Rails 3: Dashing to the Finish

Regex Constraint

get "/:id" => "posts#index", :id => /\d+/

Page 78: Rails 3: Dashing to the Finish

Request-Based Constraint

get "/mobile" => "posts#index", :constraints => {:user_agent => /iPhone/}

Page 79: Rails 3: Dashing to the Finish

Request-Based Constraint

get "/mobile" => "posts#index", :constraints => {:user_agent => /iPhone/}, :defaults => {:mobile => true}

Page 80: Rails 3: Dashing to the Finish

Request-Based Constraint

get "/mobile" => "posts#index", :user_agent => /iPhone/, :mobile => true

Page 81: Rails 3: Dashing to the Finish

Object Constraints

class DubDubConstraint def self.matches?(request) request.host =~ /^(www\.)/ endend

get "/" => "posts#index", :constraints => DubDubConstraint

Page 82: Rails 3: Dashing to the Finish

Rack

Page 83: Rails 3: Dashing to the Finish

Equivalent

get "/posts" => "posts#index"

Page 84: Rails 3: Dashing to the Finish

Equivalent

get "/posts" => "posts#index"

get "/posts" => PostsController.action(:index)

Page 85: Rails 3: Dashing to the Finish

Rack

>> a = PostsController.action(:index)

Page 86: Rails 3: Dashing to the Finish

Rack

>> a = PostsController.action(:index)=> #<Proc:0x0000000103d050d0@/Users/wycats/Code/rails/actionpack/lib/action_controller/metal.rb:123>

Page 87: Rails 3: Dashing to the Finish

Rack

>> a = PostsController.action(:index)=> #<Proc:0x0000000103d050d0@/Users/wycats/Code/rails/actionpack/lib/action_controller/metal.rb:123> >> e = Rack::MockRequest.env_for("/")

Page 88: Rails 3: Dashing to the Finish

Rack

>> a = PostsController.action(:index)=> #<Proc:0x0000000103d050d0@/Users/wycats/Code/rails/actionpack/lib/action_controller/metal.rb:123> >> e = Rack::MockRequest.env_for("/")=> {"SERVER_NAME"=>"example.org", "CONTENT_LENGTH"=>"0", ...}

Page 89: Rails 3: Dashing to the Finish

Rack

>> a = PostsController.action(:index)=> #<Proc:0x0000000103d050d0@/Users/wycats/Code/rails/actionpack/lib/action_controller/metal.rb:123> >> e = Rack::MockRequest.env_for("/")=> {"SERVER_NAME"=>"example.org", "CONTENT_LENGTH"=>"0", ...}>> e.call(a)

Page 90: Rails 3: Dashing to the Finish

Rack

>> a = PostsController.action(:index)=> #<Proc:0x0000000103d050d0@/Users/wycats/Code/rails/actionpack/lib/action_controller/metal.rb:123> >> e = Rack::MockRequest.env_for("/")=> {"SERVER_NAME"=>"example.org", "CONTENT_LENGTH"=>"0", ...}>> e.call(a)=> [200, {"ETag"=> '"eca5953f36da05ff351d712d904e"', ...}, ["Hello World"]]

Page 91: Rails 3: Dashing to the Finish

Match to Rack

class MyApp def call(env) [200, {"Content-Type" => "text/html"}, ["Hello World"]] endend

get "/" => MyApp.new

Page 92: Rails 3: Dashing to the Finish

Redirection

get "/" => redirect("/foo")

Page 93: Rails 3: Dashing to the Finish

Redirection

get "/" => redirect("/foo")

get "/:id" => redirect("/posts/%{id}")get "/:id" => redirect("/posts/%s")

Page 94: Rails 3: Dashing to the Finish

Redirection

get "/" => redirect("/foo")

get "/:id" => redirect("/posts/%{id}")get "/:id" => redirect("/posts/%s")

get "/:id" => redirect { |params, req| ...}

Page 95: Rails 3: Dashing to the Finish

Rack Appdef redirect(*args, &block) options = args.last.is_a?(Hash) ? args.pop : {}

path = args.shift || block path_proc = path.is_a?(Proc) ? path : proc { |params| path % params } status = options[:status] || 301 body = 'Moved Permanently'

lambda do |env| req = Request.new(env)

params = [req.symbolized_path_parameters] params << req if path_proc.arity > 1

uri = URI.parse(path_proc.call(*params)) uri.scheme ||= req.scheme uri.host ||= req.host uri.port ||= req.port unless req.port == 80

headers = { 'Location' => uri.to_s, 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s } [ status, headers, [body] ] endend

Page 96: Rails 3: Dashing to the Finish

Rack Appdef redirect(*args, &block) options = args.last.is_a?(Hash) ? args.pop : {}

path = args.shift || block path_proc = path.is_a?(Proc) ? path : proc { |params| path % params } status = options[:status] || 301 body = 'Moved Permanently'

lambda do |env| req = Request.new(env)

params = [req.symbolized_path_parameters] params << req if path_proc.arity > 1

uri = URI.parse(path_proc.call(*params)) uri.scheme ||= req.scheme uri.host ||= req.host uri.port ||= req.port unless req.port == 80

headers = { 'Location' => uri.to_s, 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s } [ status, headers, [body] ] endend

redirect(*args, &block)

Page 97: Rails 3: Dashing to the Finish

Rack Applambda do |env| req = Request.new(env)

params = [req.symbolized_path_parameters] params << req if path_proc.arity > 1

uri = URI.parse(path_proc.call(*params)) uri.scheme ||= req.scheme uri.host ||= req.host uri.port ||= req.port unless req.port == 80

headers = { 'Location' => uri.to_s, 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s } [ status, headers, [body] ]end

Page 98: Rails 3: Dashing to the Finish

Rack Applambda do |env| req = Request.new(env)

params = [req.symbolized_path_parameters] params << req if path_proc.arity > 1

uri = URI.parse(path_proc.call(*params)) uri.scheme ||= req.scheme uri.host ||= req.host uri.port ||= req.port unless req.port == 80

headers = { 'Location' => uri.to_s, 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s } [ status, headers, [body] ]end

[ status, headers, [body] ]

Page 99: Rails 3: Dashing to the Finish

Resources

Page 100: Rails 3: Dashing to the Finish

Resources

resources :magazines do resources :adsend

Page 101: Rails 3: Dashing to the Finish

Member Resources

resources :photos do member do get :preview get :print endend

Page 102: Rails 3: Dashing to the Finish

One-Offs

resources :photos do get :preview, :on => :memberend

Page 103: Rails 3: Dashing to the Finish

Collections

resources :photos do collection do get :search endend

Page 104: Rails 3: Dashing to the Finish

Combination

scope :module => "admin" do constraints IpBlacklist do resources :posts, :comments endend

Page 105: Rails 3: Dashing to the Finish

Recent

Page 106: Rails 3: Dashing to the Finish

#mount

Page 107: Rails 3: Dashing to the Finish

Rack Endpoint

class MountedEndpoint def call(env) head = {"Content-Type" => "text/html"} body = "script: #{env["SCRIPT_NAME"]}" body += "path: #{env["PATH_INFO"]}" [200, head, [body]] endend

Page 108: Rails 3: Dashing to the Finish

Mounting

class MountedEndpoint def call(env) head = {"Content-Type" => "text/html"} body = "script: #{env["SCRIPT_NAME"]}" body += "path: #{env["PATH_INFO"]}" [200, head, [body]] endend

mount "/end", :at => MountedEndpoint.new

Page 109: Rails 3: Dashing to the Finish

Mounting

class MountedEndpoint def call(env) head = {"Content-Type" => "text/html"} body = "script: #{env["SCRIPT_NAME"]}" body += "path: #{env["PATH_INFO"]}" [200, head, [body]] endend

mount "/end", :at => MountedEndpoint.new

# "/end/point" =># script: /end# path: /point

Page 110: Rails 3: Dashing to the Finish

Sinatra!

Page 111: Rails 3: Dashing to the Finish

ActiveRecord

Page 112: Rails 3: Dashing to the Finish

New Chainable, Lazy API

Page 113: Rails 3: Dashing to the Finish

Chainable Methods

★ select★ from★ where★ joins★ having★ group

★ order★ limit★ offset★ includes★ lock★ readonly

Page 114: Rails 3: Dashing to the Finish

Controller

def index @posts = Post. where(:published => true). order("publish_date desc")end

Page 115: Rails 3: Dashing to the Finish

Model

def index @posts = Post.publishedend

class Post < ActiveRecord::Base scope :published, where(:published => true). order("publish_date desc")end

Page 116: Rails 3: Dashing to the Finish

Model

class Post < ActiveRecord::Base scope :desc, order("publish_date desc")

scope :published, where(:published => true).descend

Page 117: Rails 3: Dashing to the Finish

Controller

def index @posts = Post. where("created_at < ?", Time.now). order("publish_date desc")end

Page 118: Rails 3: Dashing to the Finish

Controller

def index @posts = Post.pastend

class Post < ActiveRecord::Base scope :desc, order("publish_date desc")

def self.past where("created_at < ?", Time.now).desc endend

Page 119: Rails 3: Dashing to the Finish

Model

class Post < ActiveRecord::Base scope :desc, order("publish_date desc") def self.past where("created_at < ?", Time.now).desc end

def self.recent(number) past.limit(5) endend

Page 120: Rails 3: Dashing to the Finish

Pagination

class PostsController < ApplicationController def index @posts = Posts.page(5, :per_page => 10) endend

class Post < ActiveRecord::Base def self.page(number, options) per_page = options[:per_page] offset(per_page * (number - 1)). limit(per_page) endend

Page 121: Rails 3: Dashing to the Finish

named_scope

with_scope

!nd(:all)

Page 122: Rails 3: Dashing to the Finish

scope

Page 123: Rails 3: Dashing to the Finish

ActionMailer

Page 124: Rails 3: Dashing to the Finish

Massive API Overhaul

Page 125: Rails 3: Dashing to the Finish

Sending Emails

def welcome(user) @user = user mail(:to => user.email, :subject => "Welcome man!")end

Page 126: Rails 3: Dashing to the Finish

welcome.text.erb

welcome.html.erb

Page 127: Rails 3: Dashing to the Finish

Layouts

layout "rails_dispatch"

def welcome(user) @user = user mail(:to => user.email, :subject => "Welcome man!")end

Page 128: Rails 3: Dashing to the Finish

rails_dispatch.text.erb

rails_dispatch.html.erb

Page 129: Rails 3: Dashing to the Finish

Be More Speci!c

def welcome(user) @user = user mail(:to => user.email, :subject => "Welcome man!") do |format| format.html format.text { render "generic" } endend

Page 130: Rails 3: Dashing to the Finish

Defaults

default :from => "[email protected]"

def welcome(user) @user = user mail(:to => user.email, :subject => "Welcome man!") do |format| format.html format.text { render "generic" } endend

Page 131: Rails 3: Dashing to the Finish

Attachments

def welcome(user) @user = user file = Rails.public_path.join("hello.pdf") contents = File.read(file) attachments["welcome.pdf"] = contents mail(:to => user.email, :subject => "Welcome man!")end

Page 132: Rails 3: Dashing to the Finish

Interceptors

class MyInterceptor def self.delivering_email(mail) original = mail.to mail.to = "[email protected]" mail.subject = "#{original}: #{mail.subject}" endend

Page 133: Rails 3: Dashing to the Finish

Interceptors

class MyInterceptor def self.delivering_email(mail) original = mail.to mail.to = "[email protected]" mail.subject = "#{original}: #{mail.subject}" endend

config.action_mailer. register_interceptor(MyInterceptor)

Page 134: Rails 3: Dashing to the Finish

Interceptors

Delivery

Observers

Page 135: Rails 3: Dashing to the Finish

delivering_mail

deliver

delivered_mail

Page 136: Rails 3: Dashing to the Finish

Bundler

Page 137: Rails 3: Dashing to the Finish

bundle install

Page 138: Rails 3: Dashing to the Finish

bundle lock

Page 139: Rails 3: Dashing to the Finish

bundle lock

Page 140: Rails 3: Dashing to the Finish

.gitignore

.dot!les

Page 141: Rails 3: Dashing to the Finish

Engine YardHeroku

chef

Page 142: Rails 3: Dashing to the Finish

Engine YardHeroku

chefcapistrano?

Page 143: Rails 3: Dashing to the Finish

gembundler.com

Page 144: Rails 3: Dashing to the Finish

gembundler.com/rails3.html

Page 145: Rails 3: Dashing to the Finish

railsdispatch.com/posts/bundler

Page 146: Rails 3: Dashing to the Finish

yehudakatz.com/2010/04/12/some-of-

the-problems-bundler-solves/

Page 147: Rails 3: Dashing to the Finish

yehudakatz.com/2010/04/17/ruby-

require-order-problems/

Page 148: Rails 3: Dashing to the Finish

Choices

Page 149: Rails 3: Dashing to the Finish

rspec-rails

Page 150: Rails 3: Dashing to the Finish

generators

controller_example

view_example

request_example

mailer_example

rake tasks

Page 151: Rails 3: Dashing to the Finish

Mailer Generator

$ script/rails g mailer welcome create app/mailers/welcome.rb invoke erb create app/views/welcome invoke rspec create spec/mailers/welcome_spec.rb

Page 152: Rails 3: Dashing to the Finish

dm-rails

Page 153: Rails 3: Dashing to the Finish

generators

append_info_to_payload

i18n_scope

IdentityMap middleware

rake tasks

Page 154: Rails 3: Dashing to the Finish

generate a resource$ rails g resource comment invoke data_mapper create app/models/comment.rb invoke test_unit create test/unit/comment_test.rb create test/fixtures/comments.yml invoke controller create app/controllers/comments_controller.rb invoke erb create app/views/commentses invoke test_unit create test/functional/comments_controller_test.rb invoke helper create app/helpers/commentses_helper.rb invoke test_unit create test/unit/helpers/comments_helper_test.rb route resources :commentses

Page 155: Rails 3: Dashing to the Finish

generate a resource$ rails g resource comment invoke data_mapper create app/models/comment.rb invoke rspec create spec/models/comment_spec.rb invoke controller create app/controllers/comments_controller.rb invoke erb create app/views/comments invoke rspec create spec/controllers/comments_controller_spec.rb create spec/views/comments invoke helper create app/helpers/comments_helper.rb invoke rspec route resources :comments

Page 156: Rails 3: Dashing to the Finish

rails g$ rails g Rails:

controller generator helper integration_test mailer metal migration model observer performance_test plugin resource scaffold scaffold_controller session_migration stylesheets

Page 157: Rails 3: Dashing to the Finish

What Else?

Page 158: Rails 3: Dashing to the Finish

Ruby 1.9 Encoding

Page 159: Rails 3: Dashing to the Finish

Mission

Page 160: Rails 3: Dashing to the Finish

You Can Assume UTF-8 Inside of Rails

Page 161: Rails 3: Dashing to the Finish

(unless you want to handle

encodings yourself)

Page 162: Rails 3: Dashing to the Finish

Testing

Page 163: Rails 3: Dashing to the Finish

RSpec Driven Effort

Page 164: Rails 3: Dashing to the Finish

Rails Testing Support Becomes Modular

Page 165: Rails 3: Dashing to the Finish

ActionController Middleware

class PostsController use MyMiddleware, :only => :indexend

Page 166: Rails 3: Dashing to the Finish

Metalbecomes

AC::Metal

Page 167: Rails 3: Dashing to the Finish
Page 168: Rails 3: Dashing to the Finish

i18nCheck Out Sven’s Talk

Last slot in conference

Page 169: Rails 3: Dashing to the Finish

Trimming ActiveSupport Dependencies

Page 170: Rails 3: Dashing to the Finish

Thanks!

Page 171: Rails 3: Dashing to the Finish

Questions?