Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ten Years of Rails Tutorials (RailsConf 2018)

Ten Years of Rails Tutorials (RailsConf 2018)

Come see how Rails has evolved over the years through the lens of introductory Rails tutorials. Marvel at Rails pre-REST, survive the merger with Merb, feel the joy & pain of the then-new asset pipeline, and watch testing techniques grow, evolve, and simplify. Leave with a deeper appreciation for where Rails came from and where it is today.

Ffda7d145b83c4b118f982401f962ca6?s=128

Michael Hartl

April 24, 2018
Tweet

Transcript

  1. None
  2. Michael Hartl @RailsTutorial TEN YEARS OF RAILS TUTORIALS

  3. https://commons.wikimedia.org/wiki/File:Robert_A._Millikan_Memorial_Library_at_Caltech.jpg

  4. https://commons.wikimedia.org/wiki/File:The_Caxton_Celebration_- _William_Caxton_showing_specimens_of_his_printing_to_King_Edward_IV_and_his_Queen.jpg

  5. 1 <?php echo "<html>" ?> 2 <?php echo "<head>" ?>

    3 <?php echo "<script src='site.js'></script>" ?> 4 <?php echo "</head>" ?> 5 <?php echo "<body>" ?> 6 <?php echo "<h1>Hello $name</h1>" ?> 7 <?php echo "<p>Hello, world!</p>" ?> 8 <?php echo "</body>" ?> 9 <?php echo "</html>" ?>
  6. None
  7. https://commons.wikimedia.org/wiki/File:Floating_Abstraction_Victor_Pasmore.jpg

  8. https://pxhere.com/en/photo/618716

  9. None
  10. https://commons.wikimedia.org/wiki/File:Sunray_clouds_amk.jpg

  11. None
  12. None
  13. None
  14. None
  15. None
  16. None
  17. https://en.wikipedia.org/wiki/700_Series_Shinkansen#/media/File:JR_Central_Shinkansen_700.jpg AHEAD OF THE CURVE

  18. $ rails new project_name

  19. $ rails project_name

  20. None
  21. https://commons.wikimedia.org/wiki/File:Reprogramming_ENIAC.png

  22. 1 create table users ( 2 id int not null

    auto_increment, 3 name varchar(100) not null, 4 hashed_password char(40) null, 5 primary key (id) 6 );
  23. 1 # app/models/user.rb 2 class User < ActiveRecord::Base 3 validates_uniqueness_of

    :screen_name, :email 4 validates_length_of :screen_name, :within => 4..20 5 validates_length_of :password, :within => 4..40 6 validates_length_of :email, :maximum => 50 7 validates_presence_of :email 8 end
  24. 1 # app/models/user.rb 2 class User < ActiveRecord::Base 3 validates_uniqueness_of

    :screen_name, :email 4 validates_length_of :screen_name, :within => 4..20 5 validates_length_of :password, :within => 4..40 6 validates_length_of :email, :maximum => 50 7 validates_presence_of :email 8 end
  25. 1 # app/models/user.rb 2 class User < ActiveRecord::Base 3 validates_uniqueness_of

    :screen_name, :email 4 validates_length_of :screen_name, :within => 4..20 5 validates_length_of :password, :within => 4..40 6 validates_length_of :email, :maximum => 50 7 validates_presence_of :email 8 end
  26. None
  27. None
  28. None
  29. 1 <!-- app/view/profile/show.rhtml --> 2 <div id="left_column"> 3 <%= render

    :partial => 'faq/sidebar_box' %> 4 </div> 5 <div id="main_content"> 6 <div id="full_name"> 7 <%= h @spec.full_name.or_else(@user.screen_name) %> 8 </div> 9 <div id="occupation"> 10 <%= h @spec.occupation %> 11 </div> 12 <div id="location"> 13 <%= h @spec.location %> 14 </div> 15 </div>
  30. 1 <!-- app/view/profile/show.rhtml --> 2 <div id="left_column"> 3 <%= render

    :partial => 'faq/sidebar_box' %> 4 </div> 5 <div id="main_content"> 6 <div id="full_name"> 7 <%= h @spec.full_name.or_else(@user.screen_name) %> 8 </div> 9 <div id="occupation"> 10 <%= h @spec.occupation %> 11 </div> 12 <div id="location"> 13 <%= h @spec.location %> 14 </div> 15 </div>
  31. 1 <!-- app/view/profile/show.rhtml --> 2 <div id="left_column"> 3 <%= render

    :partial => 'faq/sidebar_box' %> 4 </div> 5 <div id="main_content"> 6 <div id="full_name"> 7 <%= h @spec.full_name.or_else(@user.screen_name) %> 8 </div> 9 <div id="occupation"> 10 <%= h @spec.occupation %> 11 </div> 12 <div id="location"> 13 <%= h @spec.location %> 14 </div> 15 </div>
  32. 1 <!-- app/views/user/register.rthml --> 2 <h2>Register</h2> 3 <% form_for :user

    do |form| %> 4 <fieldset> 5 <legend>Enter Your Details</legend> 6 <div class="form_row"> 7 <label for="screen_name">Screen name:</label> 8 <%= form.text_field :screen_name %> 9 </div> 10 <div class="form_row"> 11 <label for="email">Email:</label> 12 <%= form.text_field :email %> 13 </div> 14 <div class="form_row"> 15 <label for="password">Password:</label> 16 <%= form.password_field :password %> 17 </div>
  33. 1 <!-- app/views/user/register.rthml --> 2 <h2>Register</h2> 3 <% form_for :user

    do |form| %> 4 <fieldset> 5 <legend>Enter Your Details</legend> 6 <div class="form_row"> 7 <label for="screen_name">Screen name:</label> 8 <%= form.text_field :screen_name %> 9 </div> 10 <div class="form_row"> 11 <label for="email">Email:</label> 12 <%= form.text_field :email %> 13 </div> 14 <div class="form_row"> 15 <label for="password">Password:</label> 16 <%= form.password_field :password %> 17 </div>
  34. 1 <!-- app/views/user/register.rthml --> 2 <h2>Register</h2> 3 <% form_for :user

    do |form| %> 4 <fieldset> 5 <legend>Enter Your Details</legend> 6 <div class="form_row"> 7 <label for="screen_name">Screen name:</label> 8 <%= form.text_field :screen_name %> 9 </div> 10 <div class="form_row"> 11 <label for="email">Email:</label> 12 <%= form.text_field :email %> 13 </div> 14 <div class="form_row"> 15 <label for="password">Password:</label> 16 <%= form.password_field :password %> 17 </div>
  35. None
  36. 1 # app/controllers/user_controller.rb 2 class UserController < ApplicationController 3 4

    def index 5 end 6 7 def register 8 @title = "Register" 9 if request.post? and params[:user] 10 @user = User.new(params[:user]) 11 if @user.save 12 flash[:notice] = "User created!" 13 redirect_to :action => "index" 14 end 15 end 16 end 17 end
  37. 1 # app/controllers/user_controller.rb 2 class UserController < ApplicationController 3 4

    def index 5 end 6 7 def register 8 @title = "Register" 9 if request.post? and params[:user] 10 @user = User.new(params[:user]) 11 if @user.save 12 flash[:notice] = "User created!" 13 redirect_to :action => "index" 14 end 15 end 16 end 17 end
  38. 1 # app/controllers/user_controller.rb 2 class UserController < ApplicationController 3 4

    def index 5 end 6 7 def register 8 @title = "Register" 9 if request.post? and params[:user] 10 @user = User.new(params[:user]) 11 if @user.save 12 flash[:notice] = "User created!" 13 redirect_to :action => "index" 14 end 15 end 16 end 17 end
  39. 1 # app/controllers/user_controller.rb 2 class UserController < ApplicationController 3 4

    def index 5 end 6 7 def register 8 @title = "Register" 9 if request.post? and params[:user] 10 @user = User.new(params[:user]) 11 if @user.save 12 flash[:notice] = "User created!" 13 redirect_to :action => "index" 14 end 15 end 16 end 17 end
  40. https://commons.wikimedia.org/wiki/File:MVC_Diagram_(Model-View-Controller).svg

  41. https://commons.wikimedia.org/wiki/File:Public_speaking.jpg

  42. 1 # config/database.yml 2 development: 3 adapter: mysql 4 database:

    rails_space_development 5 username: root 6 password: 7 host: localhost 8 test: 9 adapter: mysql 10 database: rails_space_test 11 username: root 12 password: 13 host: localhost 14 production: 15 adapter: mysql 16 database: rails_space_production 17 username: root 18 password: <your password> 19 host: localhost
  43. 1 # config/database.yml 2 development: 3 adapter: mysql 4 database:

    rails_space_development 5 username: root 6 password: 7 host: localhost 8 test: 9 adapter: mysql 10 database: rails_space_test 11 username: root 12 password: 13 host: localhost 14 production: 15 adapter: mysql 16 database: rails_space_production 17 username: root 18 password: <your password> 19 host: localhost
  44. None
  45. None
  46. None
  47. None
  48. https://www.goodfreephotos.com/united-states/pennsylvania/pittsburgh/bridge-over-the-river-in-pittsburgh-pennsylvania.jpg.php

  49. None
  50. 1 # test/functional/user_controller_test.rb 2 # Test a valid login. 3

    def test_login_success 4 try_to_login @valid_user, :remember_me => "0" 5 assert logged_in? 6 assert_equal @valid_user.id, session[:user_id] 7 assert_equal "User #{@valid_user.name} logged in!”, 8 flash[:notice] 9 assert_response :redirect 10 assert_redirected_to :action => "index" 11 end
  51. https://commons.wikimedia.org/wiki/File:Sunray_clouds_amk.jpg

  52. 1 # test/functional/user_controller_test.rb 2 def test_login_success 3 try_to_login @valid_user, :remember_me

    => "0" 4 assert logged_in? 5 assert_equal @valid_user.id, session[:user_id] 6 assert_equal "User logged in!", flash[:notice] 7 assert_response :redirect 8 assert_redirected_to :action => "index" 9 end
  53. 1 # test/fixtures/users.yml 2 valid_user: 3 id: 1 4 screen_name:

    millikan 5 email: ram@example.com 6 password: electron 7 8 invalid_user: 9 id: 2 10 screen_name: aa/noyes 11 email: anoyes@example,com 12 password: sun
  54. None
  55. 1 # spec/controllers/sessions_controller_spec.rb 2 describe SessionsController do 3 4 describe

    "POST 'create'" do 5 6 describe "with valid email and password" do 7 before(:each) do 8 @user = Factory(:user) 9 @attr = { :email => @user.email, 10 :password => @user.password } 11 end 12 13 it "should sign the user in" do 14 post :create, :session => @attr 15 controller.current_user.should == @user 16 controller.should be_signed_in 17 end
  56. 1 # spec/controllers/sessions_controller_spec.rb 2 describe SessionsController do 3 4 describe

    "POST 'create'" do 5 6 describe "with valid email and password" do 7 before(:each) do 8 @user = Factory(:user) 9 @attr = { :email => @user.email, 10 :password => @user.password } 11 end 12 13 it "should sign the user in" do 14 post :create, :session => @attr 15 controller.current_user.should == @user 16 controller.should be_signed_in 17 end
  57. 1 # spec/controllers/sessions_controller_spec.rb 2 describe SessionsController do 3 4 describe

    "POST 'create'" do 5 6 describe "with valid email and password" do 7 before(:each) do 8 @user = Factory(:user) 9 @attr = { :email => @user.email, 10 :password => @user.password } 11 end 12 13 it "should sign the user in" do 14 post :create, :session => @attr 15 controller.current_user.should == @user 16 controller.should be_signed_in 17 end
  58. http://www.picserver.org/c/cucumber.html

  59. 1 # features/signing_in.feature 2 Feature: Signing in 3 4 Scenario:

    Successful signin 5 Given a user visits the signin page 6 And the user has an account 7 When the user submits valid signin information 8 Then they should see their profile page 9 And they should see a signout link
  60. 1 # features/step_definitions/authentication_steps.rb 2 Given /^a user visits the signin

    page$/ do 3 visit signin_path 4 end 5 6 When /^they submit invalid signin information$/ do 7 click_button "Sign in" 8 end 9 10 Then /^they should see an error message$/ do 11 page.should have_selector('div.alert.alert-error') 12 end
  61. https://www.flickr.com/photos/42181172@N02/32106551634/

  62. 1 # test/functional/user_controller_test.rb 2 def test_login_success 3 try_to_login @valid_user, :remember_me

    => "0" 4 assert logged_in? 5 assert_equal @valid_user.id, session[:user_id] 6 assert_equal "User logged in!", flash[:notice] 7 assert_response :redirect 8 assert_redirected_to :action => "index" 9 end
  63. 1 # test/integration/users_login_test.rb 2 test "login with valid information" do

    3 get login_path 4 post login_path, params: { 5 session: { email: @user.email, 6 password: 'password' } } 7 assert is_logged_in? 8 assert_redirected_to @user 9 follow_redirect! 10 assert_template 'users/show' 11 end
  64. 1 # test/fixtures/users.yml 2 valid_user: 3 id: 1 4 screen_name:

    millikan 5 email: ram@example.com 6 password: electron 7 8 invalid_user: 9 id: 2 10 screen_name: aa/noyes 11 email: anoyes@example,com 12 password: sun
  65. 1 # test/fixtures/users.yml 2 michael: 3 name: Michael Example 4

    email: michael@example.com 5 password_digest: <%= User.digest('password') %> 6 admin: true 7 activated: true 8 activated_at: <%= Time.zone.now %> 9 10 archer: 11 name: Sterling Archer 12 email: duchess@example.gov 13 password_digest: <%= User.digest('password') %> 14 activated: true 15 activated_at: <%= Time.zone.now %>
  66. 1 # test/fixtures/users.yml 2 michael: 3 name: Michael Example 4

    email: michael@example.com 5 password_digest: <%= User.digest('password') %> 6 admin: true 7 activated: true 8 activated_at: <%= Time.zone.now %> 9 10 archer: 11 name: Sterling Archer 12 email: duchess@example.gov 13 password_digest: <%= User.digest('password') %> 14 activated: true 15 activated_at: <%= Time.zone.now %>
  67. None
  68. https://en.wikipedia.org/wiki/700_Series_Shinkansen#/media/File:JR_Central_Shinkansen_700.jpg PUSHING THE ENVELOPE

  69. https://commons.wikimedia.org/wiki/File:WTF_Josh_Bluntschli_Old_car.JPG

  70. https://commons.wikimedia.org/wiki/File:Yellow_Lamborghini_Gallardo_edit2.jpg

  71. 1 create table users ( 2 id int not null

    auto_increment, 3 name varchar(100) not null, 4 hashed_password char(40) null, 5 primary key (id) 6 );
  72. https://pxhere.com/en/photo/634690 MIGRATIONS

  73. 1 # db/migrate/001_create_users.rb 2 class CreateUsers < ActiveRecord::Migration 3 def

    self.up 4 create_table :users do |t| 5 # t.column :name, :string 6 end 7 end 8 9 def self.down 10 drop_table :users 11 end 12 end
  74. 1 # db/migrate/timestamp_create_users.rb 2 class CreateUsers < ActiveRecord::Migration[5.0] 3 def

    change 4 create_table :users do |t| 5 t.string :name 6 t.string :email 7 8 t.timestamps 9 end 10 end 11 end
  75. $ rake db:migrate

  76. $ rails db:migrate

  77. ASSET PIPELINE

  78. # Before the asset pipeline public/images public/javascripts public/stylesheets

  79. # After the asset pipeline app/assets/images app/assets/javascripts app/assets/stylesheets

  80. https://pxhere.com/en/photo/948971

  81. None
  82. None
  83. None
  84. # After the asset pipeline app/assets/images app/assets/javascripts app/assets/stylesheets

  85. # After the asset pipeline app/assets/images app/assets/javascripts app/assets/stylesheets application-908e25f4bf641868d8683022a5b62f54.css

  86. None
  87. https://pxhere.com/en/photo/545993 SECURITY

  88. 1 # app/controllers/user_controller.rb 2 def register 3 @title = "Register"

    4 if request.post? and params[:user] 5 @user = User.new(params[:user]) 6 if @user.save 7 flash[:notice] = "User created!" 8 redirect_to :action => "index" 9 end 10 end 11 end
  89. 1 # app/controllers/user_controller.rb 2 def register 3 @title = "Register"

    4 if request.post? and params[:user] 5 @user = User.new(params[:user]) 6 if @user.save 7 flash[:notice] = "User created!" 8 redirect_to :action => "index" 9 end 10 end 11 end
  90. 1 # app/controllers/users_controller.rb 2 def create 3 @user = User.new(user_params)

    4 if @user.save 5 log_in @user 6 flash[:success] = "Welcome to the Sample App!" 7 redirect_to @user 8 else 9 render 'new' 10 end 11 end 12 13 private 14 15 def user_params 16 params.require(:user).permit(:name, :email, :password, 17 :password_confirmation) 18 end
  91. 1 # app/controllers/users_controller.rb 2 def create 3 @user = User.new(user_params)

    4 if @user.save 5 log_in @user 6 flash[:success] = "Welcome to the Sample App!" 7 redirect_to @user 8 else 9 render 'new' 10 end 11 end 12 13 private 14 15 def user_params 16 params.require(:user).permit(:name, :email, :password, 17 :password_confirmation) 18 end
  92. 1 # app/controllers/users_controller.rb 2 def create 3 @user = User.new(user_params)

    4 if @user.save 5 log_in @user 6 flash[:success] = "Welcome to the Sample App!" 7 redirect_to @user 8 else 9 render 'new' 10 end 11 end 12 13 private 14 15 def user_params 16 params.require(:user).permit(:name, :email, :password, 17 :password_confirmation) 18 end
  93. 1 <!-- app/view/profile/show.rhtml --> 2 <div id="left_column"> 3 <%= render

    :partial => 'faq/sidebar_box' %> 4 </div> 5 <div id="main_content"> 6 <div id="full_name"> 7 <%= h @spec.full_name.or_else(@user.screen_name) %> 8 </div> 9 <div id="occupation"> 10 <%= h @spec.occupation %> 11 </div> 12 <div id="location"> 13 <%= h @spec.location %> 14 </div> 15 </div>
  94. 1 <!-- app/view/profile/show.rhtml --> 2 <div id="left_column"> 3 <%= render

    :partial => 'faq/sidebar_box' %> 4 </div> 5 <div id="main_content"> 6 <div id="full_name"> 7 <%= h @spec.full_name.or_else(@user.screen_name) %> 8 </div> 9 <div id="occupation"> 10 <%= h @spec.occupation %> 11 </div> 12 <div id="location"> 13 <%= h @spec.location %> 14 </div> 15 </div>
  95. 1 <!-- app/views/users/show.html.erb --> 2 <% provide(:title, @user.name) %> 3

    <div class="row"> 4 <aside class="col-md-4"> 5 <section> 6 <h1> 7 <%= gravatar_for @user %> 8 <%= @user.name %> 9 </h1> 10 </section> 11 . 12 . 13 . 14 </aside> 15 </div>
  96. 1 <!-- app/views/users/show.html.erb --> 2 <% provide(:title, @user.name) %> 3

    <div class="row"> 4 <aside class="col-md-4"> 5 <section> 6 <h1> 7 <%= gravatar_for @user %> 8 <%= @user.name %> 9 </h1> 10 </section> 11 . 12 . 13 . 14 </aside> 15 </div>
  97. 1 <!-- app/views/users/show.html.erb --> 2 <% provide(:title, @user.name) %> 3

    <div class="row"> 4 <aside class="col-md-4"> 5 <section> 6 <h1> 7 <%= gravatar_for @user %> 8 <%= sanitize @user.name %> 9 </h1> 10 </section> 11 . 12 . 13 . 14 </aside> 15 </div>
  98. 1 <!-- app/views/users/show.html.erb --> 2 <% provide(:title, @user.name) %> 3

    <div class="row"> 4 <aside class="col-md-4"> 5 <section> 6 <h1> 7 <%= gravatar_for @user %> 8 <%= raw @user.name %> 9 </h1> 10 </section> 11 . 12 . 13 . 14 </aside> 15 </div>
  99. https://www.flickr.com/photos/tambako/3557843402/ REST

  100. 1 class UsersController < ApplicationController 2 3 def index 4

    end 5 6 def show 7 end 8 9 def new 10 end 11 12 def edit 13 end 14 15 def create 16 end 17 18 def update 19 end 20 21 def destroy 22 end 23 end
  101. https://pxhere.com/en/photo/948971

  102. None
  103. None
  104. None
  105. 1 # app/controllers/user_controller.rb 2 def register 3 @title = "Register"

    4 if param_posted?(:user) 5 @user = User.new(params[:user]) 6 if @user.save 7 @user.login!(session) 8 flash[:notice] = "User created!" 9 redirect_to_forwarding_url 10 else 11 @user.clear_password! 12 end 13 end 14 end
  106. 1 # app/controllers/user_controller.rb 2 def register 3 @title = "Register"

    4 if param_posted?(:user) 5 @user = User.new(params[:user]) 6 if @user.save 7 @user.login!(session) 8 flash[:notice] = "User created!" 9 redirect_to_forwarding_url 10 else 11 @user.clear_password! 12 end 13 end 14 end
  107. 1 # depot_final/app/controllers/login_controller.rb: 2 class LoginController < ApplicationController 3 before_filter

    :authorize, :except => :login 4 5 def index 6 @total_orders = Order.count 7 @pending_orders = Order.count_pending 8 end 9 . 10 . 11 . 12 end
  108. 1 # depot_final/app/controllers/login_controller.rb: 2 class LoginController < ApplicationController 3 before_filter

    :authorize, :except => :login 4 5 def index 6 @total_orders = Order.count 7 @pending_orders = Order.count_pending 8 end 9 . 10 . 11 . 12 end
  109. 1 # app/controllers/sessions_controller.rb 2 class SessionsController < ApplicationController 3 4

    def new 5 end 6 7 def create 8 email = params[:session][:email].downcase 9 password = params[:session][:password] 10 user = User.find_by(email: email) 11 if user && user.authenticate(password) 12 . 13 . 14 . 15 end 16 end
  110. 1 # app/controllers/sessions_controller.rb 2 class SessionsController < ApplicationController 3 4

    def new 5 end 6 7 def create 8 email = params[:session][:email].downcase 9 password = params[:session][:password] 10 user = User.find_by(email: email) 11 if user && user.authenticate(password) 12 . 13 . 14 . 15 end 16 end
  111. 1 # app/controllers/sessions_controller.rb 2 class SessionsController < ApplicationController 3 4

    def new 5 end 6 7 def create 8 email = params[:session][:email].downcase 9 password = params[:session][:password] 10 user = User.find_by(email: email) 11 if user && user.authenticate(password) 12 . 13 . 14 . 15 end 16 end
  112. 1 # app/controllers/user_controller.rb 2 def register 3 @title = "Register"

    4 if param_posted?(:user) 5 @user = User.new(params[:user]) 6 if @user.save 7 @user.login!(session) 8 flash[:notice] = "User created!" 9 redirect_to_forwarding_url 10 else 11 @user.clear_password! 12 end 13 end 14 end
  113. 1 # app/controllers/user_controller.rb 2 def register 3 @title = "Register"

    4 if param_posted?(:user) 5 @user = User.new(params[:user]) 6 if @user.save 7 @user.login!(session) 8 flash[:notice] = "User created!" 9 redirect_to_forwarding_url 10 else 11 @user.clear_password! 12 end 13 end 14 end
  114. 1 # app/controllers/users_controller.rb 2 def create 3 @user = User.new(user_params)

    4 if @user.save 5 log_in @user 6 flash[:success] = "Welcome to the Sample App!" 7 redirect_to @user 8 else 9 render 'new' 10 end 11 end
  115. 1 # app/controllers/users_controller.rb 2 def create 3 @user = User.new(user_params)

    4 if @user.save 5 log_in @user 6 flash[:success] = "Welcome to the Sample App!" 7 redirect_to @user 8 else 9 render 'new' 10 end 11 end
  116. 1 # app/controllers/users_controller.rb 2 def create 3 @user = User.new(user_params)

    4 if @user.save 5 @user.send_activation_email 6 flash[:info] = "Check email to activate" 7 redirect_to root_url 8 else 9 render 'new' 10 end 11 end https://commons.wikimedia.org/wiki/File:Lewis_Hamilton_2017_Malaysia_FP2.jpg
  117. 1 # app/controllers/users_controller.rb 2 def create 3 @user = User.new(user_params)

    4 if @user.save 5 @user.send_activation_email 6 flash[:info] = "Check email to activate" 7 redirect_to root_url 8 else 9 render 'new' 10 end 11 end https://commons.wikimedia.org/wiki/File:Lewis_Hamilton_2017_Malaysia_FP2.jpg
  118. ECOSYSTEM

  119. None
  120. None
  121. None
  122. None
  123. None
  124. None
  125. None
  126. None
  127. $ heroku create $ git push heroku

  128. https://commons.wikimedia.org/wiki/File:Public_speaking.jpg

  129. None
  130. LOOKING FORWARD

  131. None
  132. None
  133. https://commons.wikimedia.org/wiki/File:Bright-sun.jpg

  134. https://www.flickr.com/photos/locosteve/5388060562 Michael Hartl @RailsTutorial TEN YEARS OF RAILS TUTORIALS

  135. https://www.flickr.com/photos/locosteve/5388060562 Michael Hartl @RailsTutorial TEN MORE YEARS OF RAILS TUTORIALS

  136. THANKS! https://www.flickr.com/photos/locosteve/5388060562 Michael Hartl @RailsTutorial TEN MORE YEARS OF RAILS

    TUTORIALS
  137. Pinned Tweet at https://twitter.com/RailsTutorial