railsチュートリアル3章まとめ

###第3章でやること
+ sample_appを作り、以後の章で改良していく
+ 静的なトップページ周りを作る
+ テストを実施し学ぶ
+ リファクタリングを学ぶ

###まずはサンプルアプリケーションを生成する

```
$ cd ~/environment
$ rails _6.0.3_ new sample_app　#バージョン指定
$ cd sample_app/
```

指定のgemfileに置き換える

```gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

gem 'rails',      '6.0.3'
gem 'puma',       '4.3.6'
gem 'sass-rails', '5.1.0'
gem 'webpacker',  '4.0.7'
gem 'turbolinks', '5.2.0'
gem 'jbuilder',   '2.9.1'
gem 'bootsnap',   '1.4.5', require: false

group :development, :test do
  gem 'sqlite3', '1.4.1'
  gem 'byebug',  '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console',           '4.0.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.1.0'
  gem 'spring-watcher-listen', '2.0.1'
end

group :test do
  gem 'capybara',                 '3.28.0'
  gem 'selenium-webdriver',       '3.142.4'
  gem 'webdrivers',               '4.1.2'
  gem 'rails-controller-testing', '1.0.4'
  gem 'minitest',                 '5.11.3'
  gem 'minitest-reporters',       '1.3.8'
  gem 'guard',                    '2.16.2'
  gem 'guard-minitest',           '2.4.6'
end

group :production do
  gem 'pg', '1.1.4'
end

# Windows ではタイムゾーン情報用の tzinfo-data gem を含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

```

installする

```bundle install --without production```
--without productionオプション＝production環境でしか使わないgemはインストールしない

####※注意　私はここで失敗しました。
ローカル環境の方はrubyのバージョンに注意してください。
私は以前ダウンロードしたRuby 3.0.0　で実施していましたが、インストールがうまくいきませんでした。
同じようになった方はこちらの記事を参考にしてみてください
https://qiita.com/kiyomasa05/items/a052e5a0ebc649990397


###バージョン管理gitを設定する

```
$ git init  #gitを初期化
$ git add -A  #ローカルディポジトリに全ての変更をUP
$ git commit -m "Initialize repository"　　　#commitメッセージ
$ git remote add origin https://github.com/<あなたのGitHubアカウント名>/sample_app.git
$ git push -u origin master　　　　#masterブランチにpush

```

Gitを使う場合は、masterブランチでずっと作業するのではなく、その都度トピックブランチを作成して作業するのがよい
トピックブランチを作りそこで作業する

```
$ git checkout -b static-pages
#static-pagesブランチを作ってチェックアウトするところまでを一気に行うコマンド
```

###READMEファイルを書き換える
Qiita記事のようにマークダウンで書くとHTMLとして認識される

書き終わったら、この変更をコミット

```
$ git commit -am "Improve the README"
#git commit -am "Message"　とすることで“すべてを変更”（-a）オプションとコミットメッセージを追加する（-m）同時にできる
```

###git hubに登録しpushする

```
$ git remote add origin https://github.com/<あなたのGitHubアカウント名>/sample_app.git
$ git push -u origin master
```

###hello worldをheroku(本番環境)へデプロイする
まずはhelloアクションとコントローラに追加し、ルーティングを設定する


```app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

  def hello
    render html: "hello, world!"
  end
end
```

```config/routes.rb
Rails.application.routes.draw do
  root 'application#hello'
end
```

変更内容をgitへpushしherokuにもpushする

```
$git commit -am "Add hello"
$ git push
$ heroku create
$ git push heroku master
```

###静的なページを作成する
開発の準備ができたので、まずは静的なページを扱う「Static Pages」コントローラーを作成する
ビューは「home」「help」を作成する　※aboutも作るが後で手動で作成する

```
$ rails generate controller StaticPages home help
      create  app/controllers/static_pages_controller.rb
      .
	  .
	  .
```

rails generateはrails gと短縮形で表せる
その他短縮系のコマンド一覧	

| 完全なコマンド | 短縮形 | 
|:-----------|------------:|  
|$ rails server|$ rails s|
|$ rails console	|$ rails c|
|$ rails generate	|$ rails g|
|$ rails test|$ rails t|
|$ bundle install|$ bundle|

次に進む前に、StaticPagesコントローラファイルをGitリポジトリに追加

```
$ git add -A
$ git commit -m "Add a Static Pages controller"
$ git push -u origin static-pages
$ git push
```

実際の開発ではこまめにgitにpushしておく
（rails チュートリアルではセクションが終わるたびにやった方がいい）

###※キャメルケースとスネークケース

単語の頭文字を大文字にしてつなぎ合わせた名前=キャメルケース　例）StaticPages
単語間にアンダースコアを加えて繋ぎ合わせた名前＝スネークケース　例）static_pages_controller.rb

``$rails generate controller StaticPages home help``
キャメルケースでStaticPagesコントローラ名生成すると
自動でスネークケースにしたファイルstatic_pages_controller.rbを自動的に生成する
``$ rails generate controller static_pages ...　``しても同じ結果になる

Rubyの慣習の問題でキャメルケースで記述する慣習がある


###コラム 3.1. 元に戻す方法

生成したコードを元に戻したい場合、例えばコントローラを生成した後で、生成したコードを削除したくなった場合
``$ rails generate controller StaticPages home help``を実行した後、
コントローラ以外にも関連ファイルを大量に生成するので、生成されたコントローラファイルを削除するだけでは元に戻らない
自動生成されたコードを元に戻すためには、新規作成されたファイルを削除するだけではなく、既存のファイルに挿入されたコードも削除する必要があります

このようなときは、rails destroyというコマンドを実行することで元に戻すことができる

```
  $ rails generate controller StaticPages home help
  $ rails destroy  controller StaticPages home help
```

モデルの自動生成についても、同様の方法で可能

```
  $ rails generate model User name:string email:string
  $ rails destroy model User
#モデル名以外の引数は不要
```

マイグレーションの変更を元に戻す方法

```
  $ rails db:migrate
#元に戻したいときは、db:rollbackで1つ前の状態に戻します。
  $ rails db:rollback
#最初の状態に戻したいときは、VERSION=0オプションを使います。
$ rails db:migrate VERSION=0

```

それぞれのマイグレーションに対してバージョン番号が付与されているため``VERSION=0``を別の数字に置き換えることによって、指定したバージョンの状態に戻すことができます。

###aboutページの手動作成　（テストを進めながら実施）

何らかの変更を行う際には、常に「自動化テスト」を作成して、機能が正しく実装されたことを確認する習慣を身につけることを推奨

テストを行うメリット

+ いざというときのセーフティネットにもなり、それ自体がアプリケーションのソースコードの「実行可能なドキュメント」にもなる
+ テストを作成する=その分コードを余分に書くこと。しかし正しく行えば、むしろテストがないときよりも確実に開発速度がアップ
+ テストが揃っていれば、バグを追うために余分な時間を使わずに済む
		
たいていの開発者は、テストを書くのに慣れてくるとテストを先に書くようになるらしい

テストをするルール

```		
・アプリケーションのコードよりも明らかにテストコードの方が短くシンプルになる（=簡単に書ける）のであれば、「先に」書く
・動作の仕様がまだ固まりきっていない場合、アプリケーションのコードを先に書き、期待する動作を「後で」書く
・セキュリティが重要な課題またはセキュリティ周りのエラーが発生した場合、テストを「先に」書く
・バグを見つけたら、そのバグを再現するテストを「先に」書き、回帰バグを防ぐ体制を整えてから修正に取りかかる
・すぐにまた変更しそうなコード（HTML構造の細部など）に対するテストは「後で」書く
・リファクタリングするときは「先に」テストを書く。特に、エラーを起こしそうなコードや止まってしまいそうなコードを集中的にテストする
```

###3.3.1 最初のテスト

Aboutページの作成をしていくが、その前にtestを書いて「失敗」することを確認する
その後testが成功するようにaboutページを書いていく

StaticPagesコントローラのデフォルトのテスト

```test/controllers/static_pages_controller_test.rb
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  test "should get home" do
    get static_pages_home_url  #GETリクエストをhomeアクションに対して発行（=送信）せよ
    assert_response :success   #リクエストに対するレスポンスは［成功］になるはず
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
  end
end
```

テストの意味はコメント参照してください

実際にテストします

```
$ rails db:migrate     # システムによっては必要
$ rails test
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
```

テストスイートは期待どおり成功するはず

その後、aboutページを作るため、testをredにし、aboutページ作成による期待することを書く

```test/controllers/static_pages_controller_test.rb
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

.
.
.
  test "should get about" do   #追加
    get static_pages_about_url
    assert_response :success
  end
end
```

この状態だとtestが通らない（エラー出る）ため、
・aboutへのルーティングとアクションを追加する
・ ``about.html.erb``を作る

```config/routes.rb
Rails.application.routes.draw do
  get  'static_pages/home'
  get  'static_pages/help'
  get  'static_pages/about'  #追加
  root 'application#hello'
end
```

```app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController

  def home
  end
  def help
  end
  def about  #追加
  end
end
```

```
$ touch app/views/static_pages/about.html.erb
```

```app/views/static_pages/about.html.erb
<h1>About</h1>
<p>
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  is a <a href="https://railstutorial.jp/#ebook">book</a> and
  <a href="https://railstutorial.jp/screencast">screencast</a>
  to teach web development with
  <a href="https://rubyonrails.org/">Ruby on Rails</a>.
  This is the sample application for the tutorial.
</p>
```

rails testの結果は green になるはず

###3.3.4 Refactor
テストがpassすればリファクタリングが行える→リファクタリングはコードを簡単にわかりやすくすること

周りくどくいろいろ書いてあるが、最終的に各ページ（home,help,about）タイトルが若干異なる＆一緒のところもあることから
※同じコードを繰り返すことはRubyの「DRY」（Don’t Repeat Yourself: 繰り返すべからず）という原則に反する
タイトルのところをリファクタリングしてく

最終的なコードはこちら

application.html.erbは各ビュー共通パーツを集められる

```app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag    'application',
                               'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>  #各ページの内容をレイアウトに挿入する
  </body>
</html>
```

```app/views/static_pages/home.html.erb
<% provide(:title, "Home") %>
<h1>Sample App</h1>
<p>
  This is the home page for the
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  sample application.
</p>
```

```app/views/static_pages/help.html.erb
<% provide(:title, "Help") %>
<h1>Help</h1>
<p>
  Get help on the Ruby on Rails Tutorial at the
  <a href="https://railstutorial.jp/help">Rails Tutorial help page</a>.
  To get help on this sample app, see the
  <a href="https://railstutorial.jp/#ebook"><em>Ruby on Rails Tutorial</em>
  book</a>.
</p>
```

```app/views/static_pages/about.html.erb
<% provide(:title, "About") %>
<h1>About</h1>
<p>
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  is a <a href="https://railstutorial.jp/#ebook">book</a> and
  <a href="https://railstutorial.jp/screencast">screencast</a>
  to teach web development with
  <a href="https://rubyonrails.org/">Ruby on Rails</a>.
  This is the sample application for the tutorial.
</p>
```

3章はこれからアプリを作るための準備①といった感じ
環境さえうまく作れれば、特に問題は発生しないかと。