Saturday, May 27, 2017

Ch 8 Completed

* I have completed chapter 8: Basic login.


* I created a branch named basic-login.
$ git checkout -b basic-login

* I generated a Sessions controller with a new action.

$ rails generate controller Sessions new

* I added the paths for Sessions controller in routes.rb
sample_app/config/routes.rb
  get    '/login',   to: 'sessions#new'
  post   '/login',   to: 'sessions#create'
  delete '/logout',  to: 'sessions#destroy'


* I updated the login_path for Sessions controller testing file.
sample_app/test/controllers/sessions_controller_test.rb

* I copied the codes for the login page from the book.
sample_app/app/views/sessions/new.html.erb
<% provide(:title, "Log in") %>
<h1>Log in</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(:session, url: login_path) do |f| %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.submit "Log in", class: "btn btn-primary" %>
    <% end %>

    <p>New user? <%= link_to "Sign up now!", signup_path %></p>
  </div>
</div>

* I copied the new, create, and destroy methods to Sessions controller.
sample_app/app/controllers/sessions_controller.rb

class SessionsController < ApplicationController

  def new
  end

  def create

    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      redirect_to user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
     
  end

  def destroy
    log_out
    redirect_to root_url
  end   
   
end

* I generated an integration test for Users login for the testing of incorrect flash (incorrect prompt) behavior.
$ rails generate integration_test users_login

* I copied the codes for Users login integration test.
sample_app/test/integration/users_login_test.rb
  test "login with invalid information" do
    get login_path
    assert_template 'sessions/new'
    post login_path, params: { session: { email: "", password: "" } }
    assert_template 'sessions/new'
    assert_not flash.empty?
    get root_path
    assert flash.empty?
  end

* Then, I ran the test in the shell command window.
$ rails test test/integration/users_login_test.rb

* I added a line include SessionsHelper in the Application controller.
sample_app/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper   
end

* I copied the codes in Sessions helper.
sample_app/app/helpers/sessions_helper.rb
module SessionsHelper

  # Logs in the given user.
  def log_in(user)
    session[:user_id] = user.id
  end

  # Returns the current logged-in user (if any).
  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end   

  # Returns true if the user is logged in, false otherwise.
  def logged_in?
    !current_user.nil?
  end   

  # Logs out the current user.
  def log_out
    session.delete(:user_id)
    @current_user = nil
  end   
   
end

* I updated the _header.html.erb partial file to add new functions to display the User profile and the Logout button.
sample_app/app/views/layouts/_header.html.erb
        <% if logged_in? %>
          <li><%= link_to "Users", '#' %></li>
          <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">
              Account <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
              <li><%= link_to "Profile", current_user %></li>
              <li><%= link_to "Settings", '#' %></li>
              <li class="divider"></li>
              <li>
                <%= link_to "Log out", logout_path, method: :delete %>
              </li>
            </ul>
          </li>
        <% else %>
          <li><%= link_to "Log in", login_path %></li>
        <% end %>

* I added the Bootstrap JavaScript library to application.js
sample_app/app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require turbolinks
//= require_tree .

* I added a digest method for use in fixtures
sample_app/app/models/user.rb
  # Returns the hash digest of the given string.
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

* I created a fixture for testing user login.
sample_app/test/fixtures/users.yml
michael:
  name: Michael Example
  email: michael@example.com
  password_digest: <%= User.digest('password') %>

* I added a line to login a new user upon sign up.
sample_app/app/controllers/users_controller.rb
  def create
    @user = User.new(user_params)
    if @user.save
      log_in @user       
      flash[:success] = "Welcome to the Sample App!"       
      redirect_to @user
    else
      render 'new'
    end
  end


* I added a method in test helper to test if a user is logged in.
sample_app/test/test_helper.rb
  # Returns true if a test user is logged in.
  def is_logged_in?
    !session[:user_id].nil?
  end

* I added the log_out method in the Sessions helper.
sample_app/app/helpers/sessions_helper.rb
  # Logs out the current user.
  def log_out
    session.delete(:user_id)
    @current_user = nil
  end

* I copied the codes from the book for the destroy method in Sessions controller.
sample_app/app/controllers/sessions_controller.rb
  def destroy
    log_out
    redirect_to root_url
  end

* I copied the codes to test for user logout.
sample_app/test/integration/users_login_test.rb
  test "login with valid information followed by logout" do
    get login_path
    post login_path, params: { session: { email:    @user.email,
                                          password: 'password' } }
    assert is_logged_in?
    assert_redirected_to @user
    follow_redirect!
    assert_template 'users/show'
    assert_select "a[href=?]", login_path, count: 0
    assert_select "a[href=?]", logout_path
    assert_select "a[href=?]", user_path(@user)
    delete logout_path
    assert_not is_logged_in?
    assert_redirected_to root_url
    follow_redirect!
    assert_select "a[href=?]", login_path
    assert_select "a[href=?]", logout_path,      count: 0
    assert_select "a[href=?]", user_path(@user), count: 0
  end

* To sum up the changes, I merged my changes back into the master branch.
$ rails test
$ git add -A
$ git commit -m "Implement basic login"
$ git checkout master
$ git merge basic-login

* Then, I pushed it onto Github.
$ rails test
$ git push

* The Github address for the sample_app project is:
https://github.com/jimmy2046/sample_app

Friday, May 26, 2017

The Sign Up Page in My Own's Style

* I went back to myapp2 (https://github.com/jimmy2046/myapp2)

* I made and switched to a new branch named sign-up. It was just the same shell command.
$ git checkout -b sign-up

* I added a debug file in the home.html.erb file.
myapp2/app/views/static_pages/home.html.erb
<%= debug(params) if Rails.env.development? %>

* I added the resources in the routes.rb file.
myapp2/config/routes.rb
Rails.application.routes.draw do
  get 'users/new'

  root 'static_pages#home'
   
# home_path
  get '/home',     to: 'static_pages#home'

# help_path   
  get '/help',    to: 'static_pages#help'

# about_path   
  get '/about',    to: 'static_pages#about'   

# contact_path
  get '/contact',  to: 'static_pages#contact'   

# signup_path   
  get  '/signup',  to: 'users#new'

  resources :users   
   
end

The first part of this blog to to make a page to show user profile.  

* I created a temporary html.erb file to show user's profile.
myapp2/app/views/users/show.html.erb
<%= @user.first_name %>, <%= @user.last_name %>, <%= @user.email %>

* I added a new method show in the Users controller.
myapp2/app/controllers/users_controller.rb
  def show
    @user = User.find(params[:id])
  end

* I create a sample user profile in Rails Console for testing.
$ rails console
User.create(first_name: "Jimmy", last_name: "Chong",
email: "jimmyc@example.com",
password: "foobar", password_confirmation: "foobar")

* I typed http://localhost:3000/users/1 in my Firefox browser to make sure the a user could be queried in the Sqlite database.

* I re-wrote show.html.erb to make a trendy style.
myapp2/app/views/users/show.html.erb
<% provide(:title, @user.first_name+" "+@user.last_name) %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

<!--
Classic Template
http://www.templatemo.com/tm-488-classic
-->
    <!-- load stylesheets -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400">  <!-- Google web font "Open Sans" -->
    <link rel="stylesheet" href="/assets/css/bootstrap.min.css">                                      <!-- Bootstrap style -->
    <link rel="stylesheet" href="/assets/css/templatemo-style.css">                                   <!-- Templatemo style -->

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
          <![endif]-->
</head>

    <body>
      
        <div class="tm-header">
            <div class="container-fluid">
                <div class="tm-header-inner">
                    <%= link_to("Sample App", root_path, :class => "navbar-brand tm-site-name") %>
            <!--        <a href="#" class="navbar-brand tm-site-name">Sample App</a>  -->
                   
                    <!-- navbar -->
                    <nav class="navbar tm-main-nav">

                        <button class="navbar-toggler hidden-md-up" type="button" data-toggle="collapse" data-target="#tmNavbar">
                            &#9776;
                        </button>
                       
                        <div class="collapse navbar-toggleable-sm" id="tmNavbar">
                            <ul class="nav navbar-nav">
                                <li class="nav-item"><%= link_to "Home", root_path, class: "nav-link" %></li>
                                <li class="nav-item"><%= link_to "Help", help_path, class: "nav-link" %></li>
                                <li class="nav-item"><%= link_to "Log in", '#', class: "nav-link" %></li>
                            </ul>
                        </div>
                    </nav> 
                </div>                                 
            </div>           
        </div>

        <div class="tm-about-img-container">
           
        </div>       

        <section class="tm-section">
            <div class="container-fluid">
                <div class="row">
                    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 text-xs-center">

                        <p class="tm-subtitle">
                        <%= @user.first_name %>, <%= @user.last_name %>, <%= @user.email %></p>
                       
                    </div>
                    <%= link_to image_tag("rails.png", alt: "Rails logo"),
            'http://rubyonrails.org/' %>
                    <%= debug(params) if Rails.env.development? %>
                       
                    </div>
                </div>
        </section>
       
        <footer class="tm-footer">
            <div class="container-fluid">
                <div class="row">
                   
                    <div class="col-xs-12 col-sm-6 col-md-6 col-lg-3 col-xl-3">
                        <div class="tm-footer-content-box tm-footer-links-container">
                       
                            <h3 class="tm-gold-text tm-title tm-footer-content-box-title">Ruby on Rails Tutorial</h3>
                            <nav>
                                <ul class="nav">
                                    <li>
                                        <%= link_to("About", about_path, :class => "tm-footer-link") %>
                                    </li>
                                    <li>
                                        <%= link_to("Contact", contact_path, :class => "tm-footer-link") %>
                                    </li>
                                    <li>
                                        <a href="http://news.railstutorial.org/" class="tm-footer-link">News</a>
                                    </li>
                                </ul>
                            </nav>
                        </div>                     
                    </div>

                    <!-- Add the extra clearfix for only the required viewport
                        http://stackoverflow.com/questions/24590222/bootstrap-3-grid-with-different-height-in-each-item-is-it-solvable-using-only
                    -->
                    <div class="clearfix hidden-lg-up"></div>
                </div>

                <div class="row">
                    <div class="col-xs-12 tm-copyright-col">
                        <p class="tm-copyright-text">Jimmy Chong 2017</p>
                    </div>
                </div>
            </div>
        </footer>

        <!-- load JS files -->
        <script src="js/jquery-1.11.3.min.js"></script>             <!-- jQuery (https://jquery.com/download/) -->
        <script src="https://www.atlasestateagents.co.uk/javascript/tether.min.js"></script> <!-- Tether for Bootstrap, http://stackoverflow.com/questions/34567939/how-to-fix-the-error-error-bootstrap-tooltips-require-tether-http-github-h -->
        <script src="js/bootstrap.min.js"></script>                 <!-- Bootstrap (http://v4-alpha.getbootstrap.com/) -->
      
</body>
</html>

* I copied the Gravatar helper method to Users helper file. I changed the original users.name variable to user.first_name.
myapp2/app/helpers/users_helper.rb
module UsersHelper
   
  # Returns the Gravatar for the given user.
  def gravatar_for(user)
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
    image_tag(gravatar_url, alt: user.first_name, class: "gravatar")
  end
   
end

* In the same time, I coded the show.html.erb file to display the Gravatar of the user.
myapp2/app/views/users/show.html.erb
<% provide(:title, @user.first_name+" "+@user.last_name) %>
...
<h1>
  <%= gravatar_for @user %>
  <%= @user.first_name %> <%= @user.last_name %>
</h1>
...

* This was the preliminary version of user show page with templatemo CSS theme. (Firefox: http://localhost:3000/users/1)

The second part is to make the user sign up form.

* I copied the Users controller file from chapter 7 of the book, which included methods: show, new, create, and user_params.
myapp2/app/controllers/users_controller.rb
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end   
   
  def new
    @user = User.new     
  end

  def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = "Welcome to the Sample App!"       
      redirect_to @user
    else
      render 'new'
    end
  end

  private

    def user_params
      params.require(:user).permit(:first_name, :last_name, :email, :password,
                                   :password_confirmation)
    end   

end

* Similarly, I copied the users/new.html.erb from the book to myapp2 project with the exception that I had to separate the name field into 2 independent first_name and last_name fields.
myapp2/app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user, url: signup_path) do |f| %>
     
      <%= f.label :first_name %>
      <%= f.text_field :first_name, class: 'form-control' %>
     
      <%= f.label :last_name %>
      <%= f.text_field :last_name, class: 'form-control' %>
     
      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Create my account", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

* I created a shared view to display sign up error messages.
$ mkdir app/views/shared

* I copied the partial html.erb file from the book to display error message in HTML format.
myapp2/app/views/shared/_error_messages.html.erb
<% if @user.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      The form contains <%= pluralize(@user.errors.count, "error") %>.
    </div>
    <ul>
    <% @user.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
<% end %>

* I added <%= render 'shared/error_messages' %> to new.html.erb Users view.
myapp2/app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user, url: signup_path) do |f| %>
      <%= render 'shared/error_messages' %>
     
      <%= f.label :first_name %>
      <%= f.text_field :first_name, class: 'form-control' %>
     
      <%= f.label :last_name %>
      <%= f.text_field :last_name, class: 'form-control' %>
     
      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Create my account", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

* I did not understand why, but I added a line post '/signup',  to: 'users#create' in config/routes.rb file to make the sign up form work.
myapp2/config/routes.rb
post '/signup',  to: 'users#create'

* I didn't realized that, in the Users controller file, the permitted params.require
is (:first_name, :last_name, :email, :password, :password_confirmation)
NOT (:name, :email, :password, :password_confirmation)
I made the correction for the above code as well.

* Next, I generated the integration test for the Users sign up module. And then, I copied the Ruby codes from the book.
$ rails generate integration_test users_signup

* I added a gem 'rails-controller-testing' in the Gemfile for the testing of Rails controller.
gem 'rails-controller-testing'

* After I had added a line gem 'rails-controller-testing' to my Gemfile, I ran bundle install
$ bundle install

* In refer to the book's exercise, I added a signup route in the routes.rb file for responding to POST requests.
myapp2/config/routes.rb
  post '/signup',  to: 'users#create'

*  I modified the form_for() line in the new.html.erb view file in the user controller.
myapp2/app/views/users/new.html.erb
    <%= form_for(@user, url: signup_path) do |f| %>

* For successful user sign up, I copied the create method from the book to the Users controller file.
myapp2/app/controllers/users_controller.rb
  def create
    @user = User.new(user_params)
      if @user.save
      flash[:success] = "Welcome to the Sample App!"         
      redirect_to @user
    else
      render 'new'
    end
  end

* Then, I added the flash message (prompt) in the application layout file.
myapp2/app/controllers/users_controller.rb
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end   
   
  def new
    @user = User.new     
  end

  def create
    @user = User.new(user_params)
      if @user.save
      flash[:success] = "Welcome to the Sample App!"         
      redirect_to @user
    else
      render 'new'
    end
  end   

  private

    def user_params
      params.require(:user).permit(:first_name, :last_name, :email, :password,
                                   :password_confirmation)
    end
   
end

* I reset the database for the first sign up.
$ rails db:migrate:reset

* The sign up page in my own style.

* The sign up success page (user profile page) in my own style.


* I added one more test case for testing a legitimate sign up scenario.
myapp2/test/integration/users_signup_test.rb
  test "valid signup information" do
    get signup_path
    assert_difference 'User.count', 1 do
      post users_path, params: { user: { first_name:  "Example",
                                         last_name: "User",
                                         email: "user@example.com",
                                         password:              "password",
                                         password_confirmation: "password" } }
    end
    follow_redirect!
    assert_template 'users/show'
  end

* At the end of today's blog, I added all untracked files, committed all changes, went back to master branch, and merged sign-up branch.
$ git add -A
$ git commit -m "Finish user signup"
$ git checkout master
$ git merge sign-up

* I enabled SSL.
myapp2/config/environments/production.rb
  config.force_ssl = true

* I enabled preload_app! in puma.rb
myapp2/config/puma.rb
preload_app!

* Finally, I ran a test and pushed it onto Github.
$ rails test
$ git add -A
$ git commit -m "Use SSL and the Puma webserver in production"
$ git push

* The Github address for the myapp2 project is
https://github.com/jimmy2046/myapp2

* Here are final version of some important programming files for today's blog:

myapp2/app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user, url: signup_path) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :first_name %>
      <%= f.text_field :first_name, class: 'form-control' %>

      <%= f.label :last_name %>
      <%= f.text_field :last_name, class: 'form-control' %>     
     
      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Create my account", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

myapp2/app/controllers/users_controller.rb
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end   
   
  def new
    @user = User.new     
  end

  def create
    @user = User.new(user_params)
      if @user.save
      flash[:success] = "Welcome to the Sample App!"         
      redirect_to @user
    else
      render 'new'
    end
  end   

  private

    def user_params
      params.require(:user).permit(:first_name, :last_name, :email, :password,
                                   :password_confirmation)
    end
   
end

myapp2/config/routes.rb
Rails.application.routes.draw do
  get 'users/new'

  root 'static_pages#home'
   
# home_path
  get '/home',     to: 'static_pages#home'

# help_path   
  get '/help',    to: 'static_pages#help'

# about_path   
  get '/about',    to: 'static_pages#about'   

# contact_path
  get '/contact',  to: 'static_pages#contact'   

# signup_path   
  get  '/signup',  to: 'users#new'

  post '/signup',  to: 'users#create'   
   
  resources :users   
   
end

myapp2/app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
                                              'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>
  <body>
    <div class="container">
      <% flash.each do |message_type, message| %>
        <div class="alert alert-<%= message_type %>"><%= message %></div>
      <% end %>       
    <%= yield %>
    </div>
  </body>   
</html>

myapp2/test/integration/users_signup_test.rb
require 'test_helper'

class UsersSignupTest < ActionDispatch::IntegrationTest

require 'test_helper'

class UsersSignupTest < ActionDispatch::IntegrationTest

  test "invalid signup information" do
    get signup_path
    assert_no_difference 'User.count' do
      post users_path, params: { user: { first_name:  "",
                                         last_name:   "",
                                         email: "user@invalid",
                                         password:              "foo",
                                         password_confirmation: "bar" } }
    end
    assert_template 'users/new'
  end   

  test "valid signup information" do
    get signup_path
    assert_difference 'User.count', 1 do
      post users_path, params: { user: { first_name:  "Example",
                                         last_name: "User",
                                         email: "user@example.com",
                                         password:              "password",
                                         password_confirmation: "password" } }
    end
    follow_redirect!
    assert_template 'users/show'
  end   
   
end

end

myapp2/app/views/shared/_error_messages.html.erb
<% if @user.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      The form contains <%= pluralize(@user.errors.count, "error") %>.
    </div>
    <ul>
    <% @user.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
<% end %>

Thursday, May 25, 2017

Completed Ch 7: Sign up

This blog follows the Ch. 7 of Michael Hartl's Ruby on Rails tutorial (https://www.railstutorial.org/book/sign_up#cha-sign_up)

* Like usual, I created and switched to a new branch sign-up.
$ git checkout -b sign-up

* I added a debug line for the application layout.

* I added the styling for the debug windows in the Customm SCSS file.

* I added the Users route in the routes.rb file.
  resources :users

* I created a new file: show.html.erb

* I added Show method in the Users controller.
  def show
    @user = User.find(params[:id])
  end

* I copied the code to users helper file to show the Gravatar of the user.
app/helpers/users_helper.rb
module UsersHelper

# Returns the Gravatar for the given user.
def gravatar_for(user)
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
image_tag(gravatar_url, alt: user.name, class: "gravatar")
end
end

* I created a views shared directory.
$ mkdir app/views/shared

* I created the error message partial file.
app/views/shared/_error_messages.html.erb

* I generated the integration test for user signup.
$ rails generate integration_test users_signup

* Finally, I added all untracked files, committed the changes, and merged the sign-up branch to master branch.
$ git add -A
$ git commit -m "Finish user signup"
$ git checkout master
$ git merge sign-up

* I enabled the Force SSL option in production environment.
config/environments/production.rb
  # Force all access to the app over SSL, use Strict-Transport-Security,
  # and use secure cookies.
  config.force_ssl = true

* I modifed the config/puma.rb file in according to book's instructions.

* Lastly, I tested the project, added all untracked files, committed the changes, and pushed it onto Github (https://github.com/jimmy2046/sample_app).
$ rails test
$ git add -A
$ git commit -m "Use SSL and the Puma webserver in production"
$ git push

* The final version of sample_app/app/views/layouts/application.html.erb partial file:
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
                                              'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">       
      <% flash.each do |message_type, message| %>
        <%= content_tag(:div, message, class: "alert alert-#{message_type}") %>
      <% end %>       
      <%= yield %>
      <%= render 'layouts/footer' %>
      <%= debug(params) if Rails.env.development? %>       
    </div>
  </body>
</html>

* sample_app/app/assets/stylesheets/custom.scss
@import "bootstrap-sprockets";
@import "bootstrap";

/* mixins, variables, etc. */

$gray-medium-light: #eaeaea;

@mixin box_sizing {
  -moz-box-sizing:    border-box;
  -webkit-box-sizing: border-box;
  box-sizing:         border-box;
}

/* universal */

body {
  padding-top: 60px;
}

section {
  overflow: auto;
}

textarea {
  resize: vertical;
}

.center {
  text-align: center;
  h1 {
    margin-bottom: 10px;
  }
}

/* typography */

h1, h2, h3, h4, h5, h6 {
  line-height: 1;
}

h1 {
  font-size: 3em;
  letter-spacing: -2px;
  margin-bottom: 30px;
  text-align: center;
}

h2 {
  font-size: 1.2em;
  letter-spacing: -1px;
  margin-bottom: 30px;
  text-align: center;
  font-weight: normal;
  color: $gray-light;
}

p {
  font-size: 1.1em;
  line-height: 1.7em;
}


/* header */

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: white;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
  &:hover {
    color: white;
    text-decoration: none;
  }
}

/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid $gray-medium-light;
  color: $gray-light;
  a {
    color: $gray;
    &:hover {
      color: $gray-darker;
    }
  }
  small {
    float: left;
  }
  ul {
    float: right;
    list-style: none;
    li {
      float: left;
      margin-left: 15px;
    }
  }
}

/* miscellaneous */

.debug_dump {
  clear: both;
  float: left;
  width: 100%;
  margin-top: 45px;
  @include box_sizing;
}

/* sidebar */

aside {
  section.user_info {
    margin-top: 20px;
  }
  section {
    padding: 10px 0;
    margin-top: 20px;
    &:first-child {
      border: 0;
      padding-top: 0;
    }
    span {
      display: block;
      margin-bottom: 3px;
      line-height: 1;
    }
    h1 {
      font-size: 1.4em;
      text-align: left;
      letter-spacing: -1px;
      margin-bottom: 3px;
      margin-top: 0px;
    }
  }
}

.gravatar {
  float: left;
  margin-right: 10px;
}

.gravatar_edit {
  margin-top: 15px;
}

/* forms */

input, textarea, select, .uneditable-input {
  border: 1px solid #bbb;
  width: 100%;
  margin-bottom: 15px;
  @include box_sizing;
}

input {
  height: auto !important;
}

#error_explanation {
  color: red;
  ul {
    color: red;
    margin: 0 0 30px 0;
  }
}

.field_with_errors {
  @extend .has-error;
  .form-control {
    color: $state-danger-text;
  }
}

* sample_app/config/routes.rb
Rails.application.routes.draw do
  get 'users/new'

  root 'static_pages#home'
  get  '/help',    to: 'static_pages#help'
  get  '/about',   to: 'static_pages#about'
  get  '/contact', to: 'static_pages#contact'
  get  '/signup',  to: 'users#new'
  post '/signup',  to: 'users#create'   
  resources :users
end

* sample_app/app/controllers/users_controller.rb
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end   
   
  def new
    @user = User.new     
  end

  def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = "Welcome to the Sample App!"       
      redirect_to @user
    else
      render 'new'
    end
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end   
   
end

* sample_app/app/helpers/users_hepler.rb
module UsersHelper

  # Returns the Gravatar for the given user.
  def gravatar_for(user)
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
    image_tag(gravatar_url, alt: user.name, class: "gravatar")
  end   

end

* sample_app/app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user, url: signup_path) do |f| %>
      <%= render 'shared/error_messages' %>
     
      <%= f.label :name %>
      <%= f.text_field :name, class: 'form-control' %>
     
      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Create my account", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

* sample_app/test/integration/users_signup_test.rb
require 'test_helper'

class UsersSignupTest < ActionDispatch::IntegrationTest

  test "invalid signup information" do
    get signup_path
    assert_no_difference 'User.count' do
      post users_path, params: { user: { name:  "",
                                         email: "user@invalid",
                                         password:              "foo",
                                         password_confirmation: "bar" } }
    end
    assert_template 'users/new'
  end   

  test "valid signup information" do
    get signup_path
    assert_difference 'User.count', 1 do
      post users_path, params: { user: { name:  "Example User",
                                         email: "user@example.com",
                                         password:              "password",
                                         password_confirmation: "password" } }
    end
    follow_redirect!
    assert_template 'users/show'
  end   
   
end

Tuesday, May 23, 2017

User model in my own style

I am continuing to make my Ruby on Rails website in my own style with borrowing some CSS theme from templatemo. I want to separate the single Name field into First Name and Last Name fields respectively.

* I went back to myapp2. There is a Github repository on:
https://github.com/jimmy2046/myapp2

* I created a branch modeling-users
$ git checkout -b modeling-users

* I generated a new controller Users
$ rails generate controller Users new

* I generated a new model User. I wanted to separated the name field into First Name and Last Name.
$ rails generate model User first_name:string last_name:string email:string

* The database migration file was:
db/migrate/20170516222225_create_users.rb
 class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :first_name
      t.string :last_name
      t.string :email

      t.timestamps
    end
  end
end 

* Then, I ran database migration command.
$ rails db:migrate
== 20170516222225 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0018s
== 20170516222225 CreateUsers: migrated (0.0019s) =============================

* And then, I wrote a test case for the db model.
myapp2/test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(first_name: "Example", last_name: "User", email: "user@example.com")
  end

  test "should be valid" do
    assert @user.valid?
  end   
   
end

* After that, I ran the db model test.
$ rails test:models
Finished in 0.110520s, 9.0481 runs/s, 9.0481 assertions/s.
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

* Next, I elaborated more about the User model and the test cases for the model test.

* In order to add the unique constraint to the email field, I created an index for the table Users and field email.
$ rails generate migration add_index_to_users_email
Running via Spring preloader in process 31393
      invoke  active_record
      create    db/migrate/20170524031347_add_index_to_users_email.rb

* I didn't forget to fill in the content of the db migration file.
myapp2/db/migrate/20170524031347_add_index_to_users_email.rb
class AddIndexToUsersEmail < ActiveRecord::Migration[5.0]
  def change
    add_index :users, :email, unique: true     
  end
end

* I saved the file 20170524031347_add_index_to_users_email.rb and ran the db migration shell command.
$ rails db:migrate
== 20170524031347 AddIndexToUsersEmail: migrating =============================
-- add_index(:users, :email, {:unique=>true})
   -> 0.0018s
== 20170524031347 AddIndexToUsersEmail: migrated (0.0019s) ====================

* To solve the violation of unique constraint of the db, I temporarily remarked (commented)  the lines in the user fixtures.
test/fixtures/users.yml
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

# one:
#  first_name: MyString
#  last_name: MyString
#  email: MyString

# two:
#  first_name: MyString
#  last_name: MyString
#  email: MyString

* I did the db migration for password digest.
$ rails generate migration add_password_digest_to_users password_digest:string

* Then, i ran db migrate.
$ rails db:migrate

* I added bcrypt in the Gemfile.
gem 'bcrypt',         '3.1.11'

* And then I ran bundle install.
$ bundle install

* This was the final version of the User model file.
myapp2/app/models/user.rb
class User < ApplicationRecord
  before_save { self.email = email.downcase }
  validates :first_name, presence: true, length: { maximum: 50 }
  validates :last_name, presence: true,  length: { maximum: 50 }   
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i   
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }   
end

* And this was the final version of the test case file for User model test.
myapp2/test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(first_name: "Example", last_name: "User", email:                     "user@example.com",
                    password: "foobar", password_confirmation: "foobar")
  end

  test "should be valid" do
    assert @user.valid?
  end   

  test "first name should be present" do
    @user.first_name = "     "
    assert_not @user.valid?
  end

  test "last name should be present" do
    @user.last_name = "     "
    assert_not @user.valid?
  end   
   
  test "email should be present" do
    @user.email = "     "
    assert_not @user.valid?
  end

  test "first name should not be too long" do
    @user.first_name = "a" * 51
    assert_not @user.valid?
  end

  test "last name should not be too long" do
    @user.last_name = "a" * 51
    assert_not @user.valid?
  end
   
  test "email should not be too long" do
    @user.email = "a" * 244 + "@example.com"
    assert_not @user.valid?
  end   

  test "email validation should accept valid addresses" do
    valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
                         first.last@foo.jp alice+bob@baz.cn]
    valid_addresses.each do |valid_address|
      @user.email = valid_address
      assert @user.valid?, "#{valid_address.inspect} should be valid"
    end
  end

  test "email validation should reject invalid addresses" do
    invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
                           foo@bar_baz.com foo@bar+baz.com]
    invalid_addresses.each do |invalid_address|
      @user.email = invalid_address
      assert_not @user.valid?, "#{invalid_address.inspect} should be invalid"
    end
  end   

  test "email addresses should be unique" do
    duplicate_user = @user.dup
    duplicate_user.email = @user.email.upcase
    @user.save
    assert_not duplicate_user.valid?
  end

  test "email addresses should be saved as lower-case" do
    mixed_case_email = "Foo@ExAMPle.CoM"
    @user.email = mixed_case_email
    @user.save
    assert_equal mixed_case_email.downcase, @user.reload.email
  end

  test "password should be present (nonblank)" do
    @user.password = @user.password_confirmation = " " * 6
    assert_not @user.valid?
  end

  test "password should have a minimum length" do
    @user.password = @user.password_confirmation = "a" * 5
    assert_not @user.valid?
  end   
   
end

* I ran a test, added all untracked files, and committed the project: myapp2.
$ rails test
$ git add -A
$ git commit -m "Make a basic User model (including secure passwords)"

* I merged the modeling users branch to master branch. And then, I pushed it onto Github.
$ git checkout master
$ git merge modeling-users
$ git push

* The URL address for current project myapp2 is https://github.com/jimmy2046/myapp2

Tuesday, May 16, 2017

Ch 6 Completed

Today, I have completed the Chapter 6 Modeling User of Michael Hartl's book.

* I created a new brach 'modeling-users'.
$ git checkout -b modeling-users

* I created a new model (database table) 'user' (singular).
$ rails generate model User name:string email:string

** Note plural convention for controller names, singular for model names.
a Users controller, but a User model
The table name is plural (users) even though the model name is singular (User)


* I ran the database migration command.
$ rails db:migrate

* I wrote some test cases for testing the User model.
test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com",
    password: "foobar", password_confirmation: "foobar")
  end

  test "should be valid" do
    assert @user.valid?
  end   

  test "name should be present" do
    @user.name = "     "
    assert_not @user.valid?
  end

  test "email should be present" do
    @user.email = "     "
    assert_not @user.valid?
  end

  test "name should not be too long" do
    @user.name = "a" * 51
    assert_not @user.valid?
  end

  test "email should not be too long" do
    @user.email = "a" * 244 + "@example.com"
    assert_not @user.valid?
  end   

  test "email validation should accept valid addresses" do
    valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
                         first.last@foo.jp alice+bob@baz.cn]
    valid_addresses.each do |valid_address|
      @user.email = valid_address
      assert @user.valid?, "#{valid_address.inspect} should be valid"
    end
  end   

  test "email validation should reject invalid addresses" do
    invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
                           foo@bar_baz.com foo@bar+baz.com foo@bar_baz..com]
    invalid_addresses.each do |invalid_address|
      @user.email = invalid_address
      assert_not @user.valid?, "#{invalid_address.inspect} should be invalid"
    end
  end   

  test "email addresses should be unique" do
    duplicate_user = @user.dup
    duplicate_user.email = @user.email.upcase     
    @user.save
    assert_not duplicate_user.valid?
  end

  test "password should be present (nonblank)" do
    @user.password = @user.password_confirmation = " " * 6
    assert_not @user.valid?
  end

  test "password should have a minimum length" do
    @user.password = @user.password_confirmation = "a" * 5
    assert_not @user.valid?
  end
       
end

* The User model file
app/models/user.rb
class User < ApplicationRecord
  before_save { self.email = email.downcase }
  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i   
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }   
end

* I ran a model test.
$ rails test:models

* I added an index to table Users field Email.
$ rails generate migration add_index_to_users_email

* I filled the email unique requirement to the db migration file.
db/migrate/[timestamp]_add_index_to_users_email.rb
class AddIndexToUsersEmail < ActiveRecord::Migration[5.0]
  def change
    add_index :users, :email, unique: true
  end
end

* Don't forget to run the db migrate command.
$ rails db:migrate

* I deleted the database fixture temporarily.
test/fixtures/users.yml
# empty

* I added a password digest for model User.
$ rails generate migration add_password_digest_to_users password_digest:string

* Then I ran the db migrate command.
$ rails db:migrate

* I addded the bcrypt gem to my Gemfile.
gem 'bcrypt',         '3.1.11'

* Then I ran bundle install.
$ bundle install

* At the end of the chapter, I commited using Git and pushed it onto Github.
$ rails test
$ git add -A
$ git commit -m "Make a basic User model (including secure passwords)"
$ git checkout master
$ git merge modeling-users
$ git push

Sunday, May 14, 2017

The Layout in My Prefered Style

I have been dreaming to put the CSS theme template that I like for hosting in my Ruby on Rails server.

In simpler speaking:

Put all the CSS files from the template to:
app/assets/stylesheets

Put all the image files from the template to:
app/assets/images

Put all the Javascript files from the template to:
app/assets/javasctripts

Put all the HTML files from the template to:
app/views/(controller_name)/

And change all the image tags to:
<%= image_tag("picture01.jpg") %>

For example, I want to apply this CSS template:
http://www.templatemo.com/tm-488-classic to my Ruby on Rails project.



First, I downloaded it to my local hard drive. And I tested the HTML5 and CSS to ensure they are working properly.

Next, I tried to start from the Chapter 3 of the book:
https://www.railstutorial.org/book/static_pages#cha-static_pages
I created a new project named myapp2. I tried to copy the codes from Ch 3, Ch 4, to Ch 5.1.1 from the book "at turbo speed".

I paused at Chapter 5 Section 5.1.2. And I prepared to copy the Template 488 Classic by Templatemo.com.

* Using Firefox, I tried to open the HTML and CSS in my local drive to verify the CSS template is working properly.
file:///home/jimmyc/html/templatemo_488_classic/index.html

* This was my original home.html.erb static page without CSS stylesheet.

* Next step, I copied the CSS files to:
app/assets/stylesheets

* Then, this is the home.html.erb static page with CSS stylesheet:

* I found that Michael Harlt's codes were not very compatible with the CSS template. So, I had to modify the codes a little bit.

* I decided NOT to use the application layout file by Michael Harlt on app/views/layouts/application.html.erb. So, I reverted the application layout as is original. It might make some repeat of codes in the html.erb pages, but it is easier for design of the web page as they are following the patterns for many free CSS templates on the internet
app/views/layouts/application.html.erb (original)
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
                                              'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
 
</head>
  <body>
    <%= yield %>
  </body>   
</html>

* I re-wrote the config/routes.rb files to make the path of those static pages more adhere to Rails style.
Rails.application.routes.draw do
  root 'static_pages#home'
   
# home_path
  get '/home',     to: 'static_pages#home'

# help_path   
  get '/help',    to: 'static_pages#help'

# about_path   
  get '/about',    to: 'static_pages#about'   

# contact_path
  get '/contact',  to: 'static_pages#contact'   

# index02_path   
  get '/index02',  to: 'static_pages#index02'
   
end

* I replaced the library path of CSS files from  href="css/ to href="/assets/css/ for all html.erb files:
<link rel="stylesheet" href="/assets/css/bootstrap.min.css">
 <!-- Bootstrap style -->

<link rel="stylesheet" href="/assets/css/templatemo-style.css">
<!-- Templatemo style -->

* In html.erb file, I re-wrote all <img> tags to <%= image_tag() %>. For example:
<!-- From: -->
  <img src="img/tm-home-img.jpg" alt="Image" class="hidden-lg-up img-fluid">
<!-- To: -->
  <%= image_tag("tm-home-img.jpg", :alt => "Image", :class => "hidden-lg-up img-fluid") %>

* Next, in the templatemo-style.css file, I wrote the image path for JPG background images:
app/assets/stylesheets/templatemo-style.css
/* old:    background-image: url('../img/tm-home-img.jpg'); */
    background-image: url('tm-home-img.jpg');
.tm-about-img-container { background-image: url('tm-about-img.jpg');    }
.tm-blog-img-container { background-image: url('tm-blog-img.jpg'); }
.tm-contact-img-container { background-image: url('tm-contact-img.jpg'); }

* In earlier step, I forgot those links on the top have their class "nav-link". So, I needed to specify a class in Rails link_to() method.

For example, original html:
<a href="about.html" class="nav-link">About</a>
Ruby on Rails html.erb :
<%= link_to "About", about_path, class: "nav-link" %>
The final top links portion in the html.erb file:
<div class="collapse navbar-toggleable-sm" id="tmNavbar">
  <ul class="nav navbar-nav">
    <li class="nav-item active">
      <%= link_to "Home", home_path, class: "nav-link" %>
    </li>
    <li class="nav-item">
      <%= link_to "Help", help_path, class: "nav-link" %>
    </li>
    <li class="nav-item">
      <%= link_to "About", about_path, class: "nav-link" %>
    </li>
  </ul>
</div>

* Now, the prelim CSS style from templatemo is applied to my Ruby on Rails page.

* It took me some time to re-wrote the codes for home.html.erb.
app/views/static_pages/home.html.erb
<% provide(:title, "Home") %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

<!--
Classic Template
http://www.templatemo.com/tm-488-classic
-->
    <!-- load stylesheets -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400">  <!-- Google web font "Open Sans" -->
    <link rel="stylesheet" href="/assets/css/bootstrap.min.css">                                      <!-- Bootstrap style -->
    <link rel="stylesheet" href="/assets/css/templatemo-style.css">                                   <!-- Templatemo style -->

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
          <![endif]-->
</head>

    <body>
      
        <div class="tm-header">
            <div class="container-fluid">
                <div class="tm-header-inner">
                    <a href="#" class="navbar-brand tm-site-name">Sample App</a>
                   
                    <!-- navbar -->
                    <nav class="navbar tm-main-nav">

                        <button class="navbar-toggler hidden-md-up" type="button" data-toggle="collapse" data-target="#tmNavbar">
                            &#9776;
                        </button>
                       
                        <div class="collapse navbar-toggleable-sm" id="tmNavbar">
                            <ul class="nav navbar-nav">
                                <li class="nav-item active"><%= link_to "Home", home_path, class: "nav-link" %></li>
                                <li class="nav-item"><%= link_to "Help", help_path, class: "nav-link" %></li>
                                <li class="nav-item"><%= link_to "Log in", '#', class: "nav-link" %></li>
                            </ul>
                        </div>
                       
                    </nav> 

                </div>                                 
            </div>           
        </div>

        <div class="tm-about-img-container">
           
        </div>       

        <section class="tm-section">
            <div class="container-fluid">
                <div class="row">
                    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 text-xs-center">
                        <h2 class="tm-gold-text tm-title">Welcome to the Sample App</h2>
                        <p class="tm-subtitle">This is the home page for the
    <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
    sample application.</p>
                       
                        <%= link_to "Sign up now!", '#', class: "tm-btn text-uppercase" %>                                               
                    </div>
                    <%= link_to image_tag("rails.png", alt: "Rails logo"),
            'http://rubyonrails.org/' %>                       
                       
                    </div>
                </div>
        </section>
       
        <footer class="tm-footer">
            <div class="container-fluid">
                <div class="row">
                   
                    <div class="col-xs-12 col-sm-6 col-md-6 col-lg-3 col-xl-3">
                        <div class="tm-footer-content-box tm-footer-links-container">
                       
                            <h3 class="tm-gold-text tm-title tm-footer-content-box-title">Ruby on Rails Tutorial</h3>
                            <nav>
                                <ul class="nav">
                                    <li><a href="#" class="tm-footer-link">About</a></li>
                                    <li><a href="#" class="tm-footer-link">Contact</a></li>
                                    <li><a href="#" class="tm-footer-link">News</a></li>
                                </ul>
                            </nav>
                        </div>                     
                    </div>

                    <!-- Add the extra clearfix for only the required viewport
                        http://stackoverflow.com/questions/24590222/bootstrap-3-grid-with-different-height-in-each-item-is-it-solvable-using-only
                    -->
                    <div class="clearfix hidden-lg-up"></div>
                </div>

                <div class="row">
                    <div class="col-xs-12 tm-copyright-col">
                        <p class="tm-copyright-text">Jimmy Chong 2017</p>
                    </div>
                </div>
            </div>
        </footer>

        <!-- load JS files -->
        <script src="js/jquery-1.11.3.min.js"></script>             <!-- jQuery (https://jquery.com/download/) -->
        <script src="https://www.atlasestateagents.co.uk/javascript/tether.min.js"></script> <!-- Tether for Bootstrap, http://stackoverflow.com/questions/34567939/how-to-fix-the-error-error-bootstrap-tooltips-require-tether-http-github-h -->
        <script src="js/bootstrap.min.js"></script>                 <!-- Bootstrap (http://v4-alpha.getbootstrap.com/) -->
      
</body>
</html>

* This is picture of the finished version of the home page with new CSS style.

* And then, I went back to the book. I skipped section 5.1.2 because I copied the CSS style from templatemo already.
 
* For 5.1.3 partial (for header and footer), I hard coded it directly in the home.html.erb page.
Site header:
<nav class="navbar tm-main-nav">
  <button class="navbar-toggler hidden-md-up" type="button" data-toggle="collapse" data-target="#tmNavbar">&#9776;
  </button>
  <div class="collapse navbar-toggleable-sm" id="tmNavbar">
    <ul class="nav navbar-nav">
      <li class="nav-item active">
        <%= link_to "Home", home_path, class: "nav-link" %>
      </li>
      <li class="nav-item">
        <%= link_to "Help", help_path, class: "nav-link" %>
      </li>
      <li class="nav-item">
         <%= link_to "Log in", '#', class: "nav-link" %>
      </li>
    </ul>
</div>
</nav> 

Site footer:
<div class="tm-footer-content-box tm-footer-links-container">
  <h3 class="tm-gold-text tm-title tm-footer-content-box-title">Ruby on Rails Tutorial</h3>
  <nav>
    <ul class="nav">
      <li>
        <%= link_to("About", about_path, :class => "tm-footer-link") %>
      </li>
      <li>
        <%= link_to("Contact", contact_path, :class => "tm-footer-link") %>
      </li>
      <li>
        <a href="http://news.railstutorial.org/" class="tm-footer-link">News</a>
      </li>
    </ul>
  </nav>
</div>                     

* I skipped section 5.2 Sass and the asset pipeline because it does not match with the free CSS template.

* I did section 5.3 Layout links already.

* For section 5.3.4 Layout link tests, I generate the integration test for the app.
$ rails generate integration_test site_layout

* The testing codes:
test/integration/site_layout_test.rb
require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest

  test "layout links" do
    get root_path
    assert_template 'static_pages/home'
    assert_select "a[href=?]", root_path, count: 2
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", contact_path
  end   
   
end 

* And then I ran the test.  
$ rails test:integration
# Running:

E

Error:
SiteLayoutTest#test_layout_links:
NoMethodError: assert_template has been extracted to a gem. To continue using it,
        add `gem 'rails-controller-testing'` to your Gemfile.
    test/integration/site_layout_test.rb:7:in `block in <class:SiteLayoutTest>'


bin/rails test test/integration/site_layout_test.rb:5
Finished in 0.555924s, 1.7988 runs/s, 0.0000 assertions/s.

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

* I deleted the line assert_template 'static_pages/home' because I was not using Michael's CSS template.
require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest

  test "layout links" do
    get root_path
    assert_select "a[href=?]", root_path, count: 2
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", contact_path
  end   
   
end

* And then, I ran the integration test and general test again and made sure that they were pass.
$ rails test:integration
Finished in 0.544734s, 1.8358 runs/s, 7.3430 assertions/s.
1 runs, 4 assertions, 0 failures, 0 errors, 0 skips

$ rails test
Finished in 0.553224s, 10.8455 runs/s, 23.4986 assertions/s.
6 runs, 13 assertions, 0 failures, 0 errors, 0 skips

* For section 5.4, I created a new User controller.
$ rails generate controller Users new

* I added a Sign up path for routes.rb
# signup_path   
  get  '/signup',  to: 'users#new'

* I chaged the sign up path for User controller test file:
require 'test_helper'

class UsersControllerTest < ActionDispatch::IntegrationTest
  test "should get new" do
    get signup_path
    assert_response :success
  end

end

* I set the sign up path for the 'Sign up now!' button.
<%= link_to "Sign up now!", signup_path, class: "tm-btn text-uppercase" %> 

* I added a custom stub view for the signup page.
app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<p>This will be a signup page for new users.</p>

* I changed the text color from gray to black in the CSS file.
app/assets/stylesheets/templatemo-style.css
body {
/*    color: #8c8c8c; */
    color: #000000;
    font-family: 'Open Sans', Helvetica, Arial, sans-serif;
    font-size: 18px;
    font-weight: 300;
    overflow-x: hidden;

* Okay, at the end of the chapter, I committed the changes using git and pushed it onto Github.
$ git add -A
$ git commit -m "Finish layout and routes"
$ git checkout master
$ git merge filling-in-layout
$ rails test
$ git push

* This is the log of Linux shell commands for today's blog.
Logs
Ch 3
$ cd ~
$ rails new myapp2
$ cd myapp2
$ bundle install
$ git init
$ git add -A
$ git commit -m "Initialize repository"
$ git commit -am "Improve the README"
$ git checkout -b static-pages
$ rails generate controller StaticPages home help
$ bundle update minitest
$ git add -A
$ git commit -m "Finish static pages"
$ git checkout master
$ git merge static-pages
$ git push -u origin --all

Ch 4:
$ git checkout -b rails-flavored-ruby
$ git commit -am "Add a full_title helper"
$ git checkout master
$ git merge rails-flavored-ruby
$ rails test
$ git push

Ch 5:
$ git checkout -b filling-in-layout
$ curl -o app/assets/images/rails.png -OL railstutorial.org/rails.png
$ rails generate integration_test site_layout
$ rails test:integration
$ rails test
$ rails generate controller Users new
$ git add -A
$ git commit -m "Finish layout and routes"
$ git checkout master
$ git merge filling-in-layout
$ rails test
$ git push

* This is the final home.html.erb codes for today. You can also find it on Github:
https://github.com/jimmy2046/myapp2/blob/master/app/views/static_pages/home.html.erb

<% provide(:title, "Home") %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

<!--
Classic Template
http://www.templatemo.com/tm-488-classic
-->
    <!-- load stylesheets -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400">  <!-- Google web font "Open Sans" -->
    <link rel="stylesheet" href="/assets/css/bootstrap.min.css">                                      <!-- Bootstrap style -->
    <link rel="stylesheet" href="/assets/css/templatemo-style.css">                                   <!-- Templatemo style -->

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
          <![endif]-->
</head>

    <body>
      
        <div class="tm-header">
            <div class="container-fluid">
                <div class="tm-header-inner">
                    <%= link_to("Sample App", root_path, :class => "navbar-brand tm-site-name") %>
            <!--        <a href="#" class="navbar-brand tm-site-name">Sample App</a>  -->
                   
                    <!-- navbar -->
                    <nav class="navbar tm-main-nav">

                        <button class="navbar-toggler hidden-md-up" type="button" data-toggle="collapse" data-target="#tmNavbar">
                            &#9776;
                        </button>
                       
                        <div class="collapse navbar-toggleable-sm" id="tmNavbar">
                            <ul class="nav navbar-nav">
                                <li class="nav-item active"><%= link_to "Home", root_path, class: "nav-link" %></li>
                                <li class="nav-item"><%= link_to "Help", help_path, class: "nav-link" %></li>
                                <li class="nav-item"><%= link_to "Log in", '#', class: "nav-link" %></li>
                            </ul>
                        </div>
                    </nav> 
                </div>                                 
            </div>           
        </div>

        <div class="tm-about-img-container">
           
        </div>       

        <section class="tm-section">
            <div class="container-fluid">
                <div class="row">
                    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 text-xs-center">
                        <h2 class="tm-gold-text tm-title">Welcome to the Sample App</h2>
                        <p class="tm-subtitle">This is the home page for the
    <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
    sample application.</p>
                       
                        <%= link_to "Sign up now!", signup_path, class: "tm-btn text-uppercase" %>                                               
                    </div>
                    <%= link_to image_tag("rails.png", alt: "Rails logo"),
            'http://rubyonrails.org/' %>                       
                       
                    </div>
                </div>
        </section>
       
        <footer class="tm-footer">
            <div class="container-fluid">
                <div class="row">
                   
                    <div class="col-xs-12 col-sm-6 col-md-6 col-lg-3 col-xl-3">
                        <div class="tm-footer-content-box tm-footer-links-container">
                       
                            <h3 class="tm-gold-text tm-title tm-footer-content-box-title">Ruby on Rails Tutorial</h3>
                            <nav>
                                <ul class="nav">
                                    <li>
                                        <%= link_to("About", about_path, :class => "tm-footer-link") %>
                                    </li>
                                    <li>
                                        <%= link_to("Contact", contact_path, :class => "tm-footer-link") %>
                                    </li>
                                    <li>
                                        <a href="http://news.railstutorial.org/" class="tm-footer-link">News</a>
                                    </li>
                                </ul>
                            </nav>
                        </div>                     
                    </div>

                    <!-- Add the extra clearfix for only the required viewport
                        http://stackoverflow.com/questions/24590222/bootstrap-3-grid-with-different-height-in-each-item-is-it-solvable-using-only
                    -->
                    <div class="clearfix hidden-lg-up"></div>
                </div>

                <div class="row">
                    <div class="col-xs-12 tm-copyright-col">
                        <p class="tm-copyright-text">Jimmy Chong 2017</p>
                    </div>
                </div>
            </div>
        </footer>

        <!-- load JS files -->
        <script src="js/jquery-1.11.3.min.js"></script>             <!-- jQuery (https://jquery.com/download/) -->
        <script src="https://www.atlasestateagents.co.uk/javascript/tether.min.js"></script> <!-- Tether for Bootstrap, http://stackoverflow.com/questions/34567939/how-to-fix-the-error-error-bootstrap-tooltips-require-tether-http-github-h -->
        <script src="js/bootstrap.min.js"></script>                 <!-- Bootstrap (http://v4-alpha.getbootstrap.com/) -->
      
</body>
</html>

* This is the result of the deployment in my own style.


References:
How to set a background image in rails from css?
http://stackoverflow.com/questions/18100650/how-to-set-a-background-image-in-rails-from-css

Ruby on Rails 5.1.0
Module ActionView::Helpers::UrlHelper
http://api.rubyonrails.org/v5.1.0/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to

adding a class to a link_to is breaking the link
http://stackoverflow.com/questions/5697512/adding-a-class-to-a-link-to-is-breaking-the-link

How to kill an abandoned process in Linux/Unix

I remembered it, then I forgot, then I remembered it, and then I forgot again. In case of a Linux/Unit process hang, I have to figure out ...