RailsでRoutingErrorが出た時の対処法(エラー)

#はじめに
##本記事について
本記事はRuby on Railsの開発をするにあたってよく出るエラーの一つ「Routing Error」が出た時の解決案をいくつか提示するためのものです。
この記事を読んだら必ず「Routing Error」が解決できる！という訳ではないですが、私も初めたての頃よく出くわしていて(今も出くわすけど)、その時の解決案を残しておこうと思い書き留めることしました。
そのためこの記事では新しい解決案があれば随時書き足していこうと思います。
また読んでみてわかりづらいところや誤った表現など見受けられましたら、ご指摘いただけるとありがたいです。

##前提
「本記事について」にもあったようにこの記事では「Routing Error」の解決案をいくつか提示していきます。
ですが、Railsの細かい説明やMVCモデル等についての説明はしません。
以下のワードは本記事では出てきますけど、詳細な説明はいたしません。
完璧に理解している必要はありませんが、ある程度知っていた方がすんなり読めるかもしれないです。

- HTTP リクエストメソッド（GET，POST）
- <%= link_to %>の書き方
- routes.rb


##環境

 この記事を書くにあたっての各種バージョンです。

| ツール    |   バージョン  |
|:-----------------:|:------------------:|
| Ruby             |   2.4.1 | 
| Rails           |   5.2.3 | 
| テキストエディタ             |    Atom.1.38.1 | 

##エラー画面
Routingエラーの画面を掲示します。
こんな画面になると思います。

<img width="1334" alt="スクリーンショット_2019_06_28_13_00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301142/f91ab81c-91d1-9119-4d51-747fd9435caa.png">


画像で青枠で囲っている箇所はエラーのタイトルとなる部分です。
ここでは**Routing Error**と書かれていますね。

#Routingとは
[Railsガイド](https://railsguides.jp/routing.html)を参照するとRoutingとは
>Railsのルーターの目的は受け取ったURLを認識し、適切なコントローラ内アクションやRackアプリケーションに割り当てます。ルーターは、ビューでこれらのパスやURLを直接ハードコードすることを避けるためにパスやURLを生成することもできます。

とあります。つまりRouting Errorが出た時は **受け取ったURLとコントローラ内アクションが対応関係にない** ことが大いに考えられます。

#見るのはroutes.rb

こうなった時は十中八九見る場所は
config/routes.rbファイルです。
私の場合は以下のようになっていました。

```ruby:config/routes.rb
Rails.application.routes.draw do
  get 'tweets/index' => 'tweets#index'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
```



#考えられる原因



##単純な書き間違え
まずはじめに考えられるのが単純な書き間違えです。
例えば、config/routes.rbファイルの中身が以下のようになっていた時、

```ruby:config/routes.rb
Rails.application.routes.draw do
  get 'tweets/index' => 'tweets#index'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
```
上記の2行目に着目してください。
これは`URL 「/tweets/index」 を受け取ったら、Tweetsコントローラーのindexアクションに飛んでください。`
という意味になります。
「=>」が矢印に見えますよね。ここから「=>」の左側(今回だと URL'tweets/index')を受け取ったら右側に記述された場所に行くというのが直感的に伝わってくると思います。

よってここのルーターにないURLを打ち込むとRouting Errorが出ることになります。
今回の場合だと、 「/tweets/idex」を打ち込むと以下のようなエラーが出てきます。

<img width="1331" alt="スクリーンショット_2019_06_28_15_27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301142/acf43f00-5751-2c11-2781-61d96c01f94e.png">


しかも実はこの文よくよく読むと全く同じことが書かれています。
上記の写真の緑色の枠線をみてください。
この文を和訳すると以下のようになります。

`GETメソッドで送られた「/tweets/idex」と一致するURLはルーター(config/routes.rb)にはありません`
となります。
確かにconfig/routes.rbにはURL「/tweets/idex」は書かれていません。
よって打ち込むURLを「/tweets/index」と書き直せばいいことになります。
Railsのエラー文は親切ですね〜。


##HTTPリクエストメソッドの書き間違え
もう一つ考えられる原因としてはHTTPリクエストメソッドの書き間違えによるエラーです。
これは例えばPOSTメソッドでURLを送っているのに、ルーター内にPOSTで記述されたURLがない時などに起こります。
例を見てみましょう。
まずは準備として、
config/routes.rbに以下のように書き換えます。

```ruby:config/routes.rb
Rails.application.routes.draw do
  get 'tweets/index' => 'tweets#index'
  get 'tweets/new' => 'tweets#new'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
```

またapp/views/tweetsにnew.html.erbファイルを作っておきます。


さて、この状態でapp/views/tweets/index.html.erbに以下のような記述をしたとします。

```ruby:index.html.erb
<%= link_to "hello", "/tweets/new",method: :post %>
```

これを実際の画面上でみると以下のようになります。

<img width="404" alt="スクリーンショット 2019-06-28 15.50.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301142/11b037e1-7062-ffc2-3499-aa1e66e95503.png">

詳細は省きますが、これは"hello"を押したらURL「/tweets/new」に**POSTメソッド**で遷移するようになっています（なぜこんなところでPOSTメソッドを使うのかは一回置いておいておきましょう）。
さて、これで"hello"を押すと"tweets/new"に遷移してくれるのでしょうか。
押してみると...以下のようなエラーがで出てしまいます。

<img width="1182" alt="スクリーンショット_2019_06_28_16_02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301142/c18ad6de-a33f-be17-3773-c2ebab5bd3b4.png">

これも緑枠を和訳すると以下のようになります。
`POSTメソッドで送られた「/tweets/new」と一致するURLはルーター(config/routes.rb)にはありません`

ここでconfing/routes.rbファイルを見てみましょう。

```ruby:config/routes.rb
Rails.application.routes.draw do
  get 'tweets/index' => 'tweets#index'
  get 'tweets/new' => 'tweets#new'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
```

確かに、ここではURL「/tweets/new」を受け取ったらtweetsコントローラーのnewアクションに遷移するためのコードは書かれています（上記3行目）。
しかしその遷移の仕方はGETメソッドです。
"hello"を押したらPOSTメソッドで「/tweets/new」に遷移するように書いたので、これだとうまくいかずエラーが出てしまいます。
以下のようにconfig/routes.rbを書き換えてみてください。

```ruby:config/routes.rb
Rails.application.routes.draw do
  get 'tweets/index' => 'tweets#index'
  post 'tweets/new' => 'tweets#new'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
```

これでもう一度押すと...うまくいきましたね。

#rails routesについて

余談ですが、自分の開発プログラムのURLとコントローラ内アクションの関係性を一覧で見る、一つの手段としてターミナル(Windowsの場合はコマンドプロンプト)に「rails routes」と打ち込んで確認する方法があります。
ターミナル(Windowsの場合はコマンドプロンプト)を開いて以下のコードを打ち込んでみてください。
また「$」は慣習的に書いていますが、実際は打ち込む必要はないです。

```ruby:ターミナル
$ rails routes
```

私の場合は打ち込んだ後、以下のような出力になりました。

<img width="1119" alt="スクリーンショット_2019_06_28_23_49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301142/d91aaaf5-dae2-23f3-bba1-537f801099b9.png">

なんか色々書かれていますが、赤枠で囲った部分に注目してみてください。
上の方に「URL Pattern」と「Controller#Action」と書かれた部分がありますね(「Prefix」の説明は今回は割愛します)。
実はこのコマンドはURLとContoller#Actionの一覧を表示してくれるためのものです。
ここを確認して、今どんなURLを打つとどこに行き着くのかを確認することができます。