Rails Tutorial 第3章学習編

#Rails Tutorial 第3章で(。´・ω・)ん?って思ったところ


```StaticPagesController.rb
def home
end

def help
end
```
なんで何も書いてないのにこれで動くんだろうと思っていました。
　⇒デフォルトの挙動に関する記述が省略されているそうです。
初学者には(。´・ω・)ん?ってなりますよね。

```rb:StaticPagesController.rb
def home
#app/views/static_pages/home.html.erbを実行(省略されている記述)
end

def help
#app/views/static_pages/help.html.erbを実行(省略されている記述)
end
```

次に躓いたのがテストです・・・。
Tech::Campのカリキュラムでは全く扱っていなかったので事前知識もなく(。´・ω・)ん?でした。

#####テスト駆動開発 TDD(Test Driven Development) </b>
テストしながら開発しようというモノらしいです。
Rails Tutorialで使っているminitestは簡易的なモノで、
一般的にはRspec と Capybara といったツールが使われるようです。

(´-ω-`)チュートリアル終えた後に学ぶ内容が増えたな・・・。

事前に固まっている仕様等は、
『テストを書く』⇒『実装する』⇒『テストする』

デザインなど作りながら変更していく物は、
『実装する』⇒『テストを書く』⇒『テストする』

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

テストをしない開発はあり得ないという事で・・・テスト書ける様になる事はすごく重要っぽいです。


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

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  test "should get home" do
    get static_pages_home_url #URLにアクセスする
    assert_response :success  #←テスト部分[HTMLページが帰ってくるか確認]
  end

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


#####そして・・・一番分からなかったのはこれ。

>3.6 高度なセットアップ
この追加の節は、テスト用設定について解説します。大きく分けると、成功/失敗の表示設定をする「minitest reporters（3.6.1）」と、ファイルの変更を検出して必要なテストだけを自動実行してくれる「Guard（3.6.2）」の２つです。この節で参考までに示したコードはそれなりに高度なので、今すぐ理解できるようになる必要はありません。

Guardはファイルシステムの変更を監視し、
例えばstatic_pages_test.rbファイルなどを変更すると自動的にテストを実行してくれるツール

あ、なんかめちゃくちゃ便利そう(*'▽')

```ruby:Guardfile
# Guardのマッチング規則を定義 
guard :minitest, spring: "bin/rails test", all_on_start: false do
  watch(%r{^test/(.*)/?(.*)_test\.rb$})
  watch('test/test_helper.rb') { 'test' }
  watch('config/routes.rb') { interface_tests }
  watch(%r{app/views/layouts/*}) { interface_tests }
  watch(%r{^app/models/(.*?)\.rb$}) do |matches|
    "test/models/#{matches[1]}_test.rb"
  end
  watch(%r{^app/controllers/(.*?)_controller\.rb$}) do |matches|
    resource_tests(matches[1])
  end
  watch(%r{^app/views/([^/]*?)/.*\.html\.erb$}) do |matches|
    ["test/controllers/#{matches[1]}_controller_test.rb"] +
    integration_tests(matches[1])
  end
  watch(%r{^app/helpers/(.*?)_helper\.rb$}) do |matches|
    integration_tests(matches[1])
  end
  
  watch('app/views/layouts/application.html.erb') do
    'test/integration/site_layout_test.rb'
  end
  watch('app/helpers/sessions_helper.rb') do
    integration_tests << 'test/helpers/sessions_helper_test.rb'
  end
  watch('app/controllers/sessions_controller.rb') do
    ['test/controllers/sessions_controller_test.rb',
     'test/integration/users_login_test.rb']
  end
  watch('app/controllers/account_activations_controller.rb') do
    'test/integration/users_signup_test.rb'
  end
  watch(%r{app/views/users/*}) do
    resource_tests('users') +
    ['test/integration/microposts_interface_test.rb']
  end
end

# 与えられたリソースに対応する統合テストを返す
def integration_tests(resource = :all)
  if resource == :all
    Dir["test/integration/*"]
  else
    Dir["test/integration/#{resource}_*.rb"]
  end
end

# インターフェースが該当するすべてのテストを返す
def interface_tests
  integration_tests << "test/controllers/"
end

# 与えられたリソースに対応するコントローラのテストを返す
def controller_test(resource)
  "test/controllers/#{resource}_controller_test.rb"
end

# 与えられたリソースに対応するすべてのテストを返す
def resource_tests(resource)
  integration_tests(resource) << controller_test(resource)
end
```

取り合えず、特定のファイルを変更したらテストフォルダ内にあるファイルを実行するという感じですね。
このファイルを設定した後に下記コマンドを実行する事で自動テスト監視が始まるようです。

```
$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
$ sudo sysctl -p
$ bundle exec guard

$ bin/spring stop    # テストが原因不明で動かなくなったら、このコマンドを実行してみる
$ bundle exec guard
```

自分でカスタマイズできるとは思えない（　＾ω＾）・・・

##簡単な内容のおさらい

#####config/routes.rb
～にアクセスがあった時、コントローラー#アクションを実行するという記述を書く

```rb:config/routes.rb
Rails.application.routes.draw do
  get  'static_pages/home'　#この記述はあまり使わない。
 #get 'static_pages/home' => "static_pages#home" こんな風に書くのが一般的な気がする。
  get  'static_pages/help'
  root 'application#hello'
end
```

#####app/controller/StaticPagesController.rb
各アクションの内容を記述する。

```rb:app/controller/StaticPagesController.rb
def home
#app/views/static_pages/home.html.erbを実行(省略されている記述)
end

def help
#app/views/static_pages/help.html.erbを実行(省略されている記述)
end
```


#####app/views/コントローラ名/xxx.html.erb
ユーザーに表示する画面はビューファイル (格納場所は app/views/コントローラ名/xxx.html.erb)
erbはembedded ruby (htmlファイルにRubyを埋め込める便利な拡張子)
<%> <%>で囲まれた部分がRubyのコード部分。

* <%=> ... <%> 記述したコードの実行結果をHTML内に表示させる場合にはこっちを使う
* <%> ... <%> 記述したコードの実行結果を表示させない場合はこっちを使う。

#####app/views/layouts/application.html.erb
共通HTML部分はapp/views/layouts/application.html.erbで共有する

```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>
```

#####provideメソッド
ページタイトルの受け渡しはprovideメソッド<% provide(:title, "Home") %>を各ビューに記述

```erb: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>
```

#####テストはtestフォルダ以下にあるファイルに記述
test/controllers/static_pages_controller_test.rbにテストを記述する事で、
各ページにアクセスした際の応答、タイトル名、ページ要素等をテストできる。

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

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  def setup
    @base_title = "Ruby on Rails Tutorial Sample App"
  end

  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Home | #{@base_title}"
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | #{@base_title}"
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | #{@base_title}"
  end
end
```

#####元に戻す方法

|項目|作成|元に戻す方法|
|:-:|:-:|:-:|
|コントローラー|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|rails db:rollback(一つ前の状態に戻す)|
|データベース|rails db:migrate| $ rails db:migrate VERSION=0(初期状態に戻す)|

#####コマンドの短縮形

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

##### おまけ まだ長過ぎるという方へ・・・ </b>
Linuxのコマンドは.bashrcというファイルを編集する事でカスタマイズできます('ω')ノ



```
#STEP1 - c9 ~/.bashrc でファイルを開く。
c9 ~/.bashrc

#STEP2 - 文末に下記の様に短縮コマンドを登録する
alias r='rails'
alias g='git'

STEP3 - source ~/.bashrc を実行して登録した短縮コマンドを読み込む
source ~/.bashrc

#STEP4
r cと入力して　rails consoleが立ち上がるか確認してみる('ω')ノ
```

##感想

Rails Tutorialの動画(29800円)を見ながら復習がてらQiitaにアウトプットしていますが、
ウェブテキスト版には記述されていない便利な機能などの解説もあったりして満足しています。
今までc9コマンドはファイルを開くのに使っていました。
c9コマンドにopenオプションを付けるとファイルが存在しない場合に新規作成されるのは眉唾でした。
やっぱり人に解説してもらう方が頭にすんなり入ってきますね。
ちょっと高いですが、動画教材もなかなかにおススメです。
Udemy・Coursera・EduXといったオンライン学習サイトで無料～低価格で様々な内容を学習できます。
※Udemyは頻繁にセールを行っていてセール中は90%近く割引になるのでセール中の購入がおススメです。
一度購入したコンテンツは何度でも見れます！内容もかなり濃いものが多いです。

[Udemy (https://www.udemy.com/)](https://www.udemy.com/)
[Coursera (https://ja.coursera.org/)](https://ja.coursera.org/)
[EdX (https://www.edx.org/)](https://www.edx.org/)

```
c9 open app/views/static_pages/about.html.erb
```

あとはcloud9上でCtrl + pでファイル検索が出来できるそうです('ω')ノ
私は毎回フォルダを開くことでどこに何があるか覚えたので最初はCtrl+pは使わない事を推奨します。
まぁ、いちいちフォルダを開くのが面倒な方は是非使ってみてください。

今回はテストという新たな内容が入ってきたので、なかなか濃い内容でした。
私は同じ内容を必ず数回読むようにしています。
特に私は物覚えが悪いので何度も繰り返してやっと覚えられる感じです。
見直してみると一回目に読んだ時とは違った気付きがあったりします。
是非、皆さんも一回だけではなく数回読み直してみてください('ω')ノ