【第3章】rails tutorial 備忘録

##セットアップ
rails newして、gemを編集して
bundle install

```
$git init
$git add -A
$git commit -m "initialize repository"
$git remote https://github.com/*******/sample__app2.git
```

##README

READMEにアプリケーションの使い方などを、記載する。
編集したら

```
$git commit -am "Imporove the README"
$git push -u origin --all
```

##gitコマンドのあれこれ

```
$git push origin --all
```
全てのローカルブランチをpushする

```
$git commit -am "gitcommand"
```
addとcommitを一度に行う。

##herokuにpush

```
$heroku create
$git push heroku master
```


新たなエラー発生。

```
error: src refspec origin does not match any.
error: failed to push some refs to 'https://git.heroku.com**********
```
どうやら、githubへのcommmitを忘れていた模様。
変更をしっかりとコミット。

```
$git push heroku master
```

## デフォルトページの変更
herokではデフォルト画面がうまく表示されないので、変更してデプロイが成功しているか確認する

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

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

rootも変更してあげる

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

herokuにpushした後、

```
$heroku open
```
で確認する。

hello worldが表示された。

##静的なページの生成

```
$rails g controller Static_Page home help

Running via Spring preloader in process 8647
      create  app/controllers/static_page_controller.rb
       route  get 'static_page/help'
       route  get 'static_page/home'
      invoke  erb
      create    app/views/static_page
      create    app/views/static_page/home.html.erb
      create    app/views/static_page/help.html.erb
      invoke  test_unit
      create    test/controllers/static_page_controller_test.rb
      invoke  helper
      create    app/helpers/static_page_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/static_page.coffee
      invoke    scss
      create      app/assets/stylesheets/static_page.scss
```
homeとhelpページを表示するためのviewsやそこにアクセスするためのrouteの生成もされている。

## 元に戻す方法
間違った名前のコントローラを作成してしまったり、もっといい名前を思いついた場合など、
作ったものを元に戻したいときは

```
$rails destroy controller StaticPage home help


modelの場合も
$rails destroy model User


```
generateをdestroyに変えてあげるだけで元に戻せる。

なお、db:migrateを元に戻すときは

```
$rails db:rollback
$rails db:rollcack VERSION=0
```
マイグレーションは逐次的に実行されるので、
例えば、三回マイグレーションしたら、現在がversion=3になる。
rollbackを一回したら、version=2に戻り
VERSION＝　に指定すれば、指定したversionに戻すことができる。


## 生成されたコード

```ruby:config/routes.rb
get "static_page/home"
get "static_page/helo"
```
上記は、getリクエストで"static_pages/home"にアクセスした場合
「static_pages」controllerの「home」アクションを呼び出すという意味になる。

```
$rails server
```
でサーバーを立ち上げた後、
http://localhost:3000/static_page/home
にアクセスすると
/views/statc_pasge/home.html.erbにさ記載されたものが表示される。

```ruby:/views/statc_pasge/home.html.erb
<h1>StaticPage#home</h1>
<p>Find me in app/views/static_page/home.html.erb</p>

```
![スクリーンショット 2019-04-09 19.31.17.png](https://qiita-image-store.s3.amazonaws.com/0/322607/c234d595-5f79-baaa-57fd-a6068e7af73a.png)


## HTTPメソッド

基本的な操作
1 GET 　ページを取得
2 POST　作成処理
3 PATCH　更新、編集処理
4 DELETE　削除処理

上記のように
メソッドと処理が必ずしも対応する訳ではないが、このような対応になる場合が多い。


## Controller

```ruby:Static_Page_controller.rb
def home
end

def help
end
```
のようにメソッドが空の場合は何の処理もせず、
viewsを呼び出し、HTMLを取得する。

## view

上記の
「●static_page」コントローラの「◎home」アクションが呼び出すviewは
views/「●static_page」の「◎home.html.erb」である。



##演習
1.Fooというコントローラを生成し、その中にbarとbazアクションを追加してみてください

```
$rails g controller Foo bar baz
```

2.Fooコントローラとそれに関連するアクションを削除してみてください。

```
rails g destroy controller Foo bar bag
```


##テスト

先にテストを書き、失敗させてから、
成功するようにコードを書き直す。




例えば、「A」位というタイトルを表示させたいとする。

現状　「B」というタイトルが表示されている。

そして、テストに
「Aというタイトルが表示しているか」というテスト先に書く。

テストを実行すると、テストは失敗（エラー）する。（「A」になるように実装してないから）

そして、テストが成功するように（「A」というタイトルが表示されるように）実装をする。

最後にテストが成功しているか、確認する。





##デフォルトのテスト

controllerの単体テスト

```ruby:test/controllers/static_pages_controller_test.rb

test "should get home" do
    get static_pages_home_url
    assert_response :success
  end

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

要はgetメソッドでこのURLにアクセスしたら、ちゃんとページが表示されるよね？
というテストになる。

rails testを実行するとテストは成功する

## 失敗するテストを書いてみる

```ruby:test/controllers/static_pages_controller_test.rb

test "should get about" do
  get static_pages_help_url
  assert_response :success
end
```
このテストはまだaboutのroute、aboutアクションやaboutのviewを作っていないのでテストは失敗する。

```
$ rails test
..
..
..
1) Error:
StaticPageControllerTest#test_should_get_about:
NameError: undefined local variable or method `static_page_about_url' for #<StaticPageControllerTest:0x007fec13ee9c18>
    test/controllers/static_page_controller_test.rb:15:in `block in <class:StaticPageControllerTest>'

3 runs, 2 assertions, 0 failures, 1 errors, 0 skips
```
エラー内容
NameError: undefined local variable or method `static_page_about_url' for #

aboutのrouteを作成していないので、
static_page_about_urlがないと言っている。


```ruby:config/routes.rb
..
..
get 'static_pages/about'
```
routeを追加して、再テストする。

```
StaticPageControllerTest#test_should_get_about:
AbstractController::ActionNotFound: The action 'about' could not be found for StaticPageController
    test/controllers/static_page_controller_test.rb:15:in `block in <class:StaticPageControllerTest>'

3 runs, 2 assertions, 0 failures, 1 errors, 0 skips
```

今度はアクションがないというエラー。

ページを表示するまでには
１ routeの作成
２　アクションの作成
３　viewの作成

が必要。
今回は、１のrouteを作成した後のテストなので
２を作っていないというエラー

2のアクションを作成した後、再テストすると
3のaboutのviewがないというエラーになるはず


```ruby:app/controllers/static_pages_controller.rb

..
..
..
def about
end
```
アクションを追加して、再テストする。

```
StaticPageControllerTest#test_should_get_about:
ActionController::UnknownFormat: StaticPageController#about is missing a template for this request format and variant.
```
template,つまりviewsがないというエラー。

```
$ touch app/views/static_page/about.html.erb
```
aboutのviewとなるファイルを作成。
そこに表示したい内容を書く。

再テスト。
```
$ rails t
..
..

Finished in 0.713622s, 4.2039 runs/s, 4.2039 assertions/s.

3 runs, 3 assertions, 0 failures, 0 errors, 0 skips
```
上記の1,2,3を全て作成したので
assert_response :success
のテストが通った。

##タイトルのテスト

assert_select "(タグ名）"
でタグが存在するか確認する

assert_select "(タグ名）","文字列”
指定したタグ内に、指定した文字列があるかテストする。

タイトルを確認するテストを書く。

```ruby:test/controllers/static_pages_controller_test.rb

test "should get home" do
 get static_pages_home_url
 assert_response :success
 assert_select "title","Home|Ruby on Rails Tutorial Sample App"

 test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | Ruby on Rails Tutorial Sample App"
  end
end
```

テストすると失敗するはず

```
1) Failure:
StaticPageControllerTest#test_should_get_home [/Users/user/tutorial2/sample_app/test/controllers/static_page_controller_test.rb:7]:
Expected at least 1 element matching "title", found 0..
Expected 0 to be >= 1.

  2) Failure:
StaticPageControllerTest#test_should_get_about [/Users/user/tutorial2/sample_app/test/controllers/static_page_controller_test.rb:19]:
Expected at least 1 element matching "title", found 0..
Expected 0 to be >= 1.

  3) Failure:
StaticPageControllerTest#test_should_get_help [/Users/user/tutorial2/sample_app/test/controllers/static_page_controller_test.rb:13]:

Expected at least 1 element matching "title", found 0..
Expected 0 to be >= 1.
```

テストを成功させるために、
各ページにタイトルを入れる。

再度、テストをして、成功。

##レイアウトと埋め込みRuby

views内で
<% %>でrubyコードを囲み、実行できる。

<%= %>にすると実行結果を出力できる。


各ページの共通部品を切り出し、
application.html.erbに移す。

```ruby:app/views/layouts/application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</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>
```

```
<%= csrf_meta_tags %>
<%= stylesheet_link_tag ... %>
<%= javascript_include_tag "application", ... %>
```
は悪意のあるコードを贈られた時にそれらをエンコードして、無効化する。

##ルーティングの設定

rootを以下のように書くとエラー

```
root 'application/home'
```
rootの場合は「/」ではなくで、「#」を使う

```
root 'application#home'
```

##演習

rootルーティングのテストを書いてみてください。

```ruby:test/controllers/static_pages_controller_test.rb
test "should get root" do
    get root_url
    assert_response :success
  end
```


## Guardを設定する

```
$ bundle exec guard init
```
Guardfileを編集して

```
$ bundle exec guard
```

Gaurdを終了するときは
Ctrl-Dキー



##　感想

理解しているところは書かずに、
ちょっと忘れているところだけ、言語化して
スピードをもっと上げて、学習することにする。