#はじめに
##本記事について
本記事は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エラーの画面を掲示します。
こんな画面になると思います。
画像で青枠で囲っている箇所はエラーのタイトルとなる部分です。
ここではRouting Errorと書かれていますね。
#Routingとは
Railsガイドを参照するとRoutingとは
Railsのルーターの目的は受け取ったURLを認識し、適切なコントローラ内アクションやRackアプリケーションに割り当てます。ルーターは、ビューでこれらのパスやURLを直接ハードコードすることを避けるためにパスやURLを生成することもできます。
とあります。つまりRouting Errorが出た時は 受け取ったURLとコントローラ内アクションが対応関係にない ことが大いに考えられます。
#見るのはroutes.rb
こうなった時は十中八九見る場所は
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ファイルの中身が以下のようになっていた時、
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」を打ち込むと以下のようなエラーが出てきます。
しかも実はこの文よくよく読むと全く同じことが書かれています。
上記の写真の緑色の枠線をみてください。
この文を和訳すると以下のようになります。
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に以下のように書き換えます。
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に以下のような記述をしたとします。
<%= link_to "hello", "/tweets/new",method: :post %>
これを実際の画面上でみると以下のようになります。
詳細は省きますが、これは"hello"を押したらURL「/tweets/new」にPOSTメソッドで遷移するようになっています(なぜこんなところでPOSTメソッドを使うのかは一回置いておいておきましょう)。
さて、これで"hello"を押すと"tweets/new"に遷移してくれるのでしょうか。
押してみると...以下のようなエラーがで出てしまいます。
これも緑枠を和訳すると以下のようになります。
POSTメソッドで送られた「/tweets/new」と一致するURLはルーター(config/routes.rb)にはありません
ここでconfing/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を書き換えてみてください。
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の場合はコマンドプロンプト)を開いて以下のコードを打ち込んでみてください。
また「$」は慣習的に書いていますが、実際は打ち込む必要はないです。
$ rails routes
私の場合は打ち込んだ後、以下のような出力になりました。
なんか色々書かれていますが、赤枠で囲った部分に注目してみてください。
上の方に「URL Pattern」と「Controller#Action」と書かれた部分がありますね(「Prefix」の説明は今回は割愛します)。
実はこのコマンドはURLとContoller#Actionの一覧を表示してくれるためのものです。
ここを確認して、今どんなURLを打つとどこに行き着くのかを確認することができます。