get "posts/:id" => "posts#show"
get "posts/new" => "posts#new"
これは問題ないのに、、、
get "posts/new" => "posts#show"
get "posts/:id" => "posts#new"
どうしてこれはエラーになるのか?
なぜなら、**「posts/:id」の「:id」**は、変数であり、
###変数を含むことで、あらゆるURLと合致してしまうから!
↓
ブラウザからリクエストされたURLが、一致してほしいURLのルーティングへと辿り着く前に、あらゆるURLを含むルーティングと合致してしまうため、このようなエラーが起こる。
##具体的に解説
####今回のルーティングエラーを理解するために、下記の2つのポイントを抑えておく。
-
ルーティングは書かれたコードを、上から順に一致するか調べていく。
-
プログラムの指示には以下のような流れがある。
1.****ブラウザがURLに一致するHTMLファイルをルーティングに要求
2.一致するルーティングが存在した場合、対応するコントローラへと道を作る
3.そのコントローラのアクションと一致するHTMLファイルをブラウザへと返す
4.受け取ったHTMLファイルをブラウザが表示する
###〜解決法〜
変数を含んだルーティングのURLを、似たようなルーティングのURLの一番下に移動してしまえばいい。
get "posts"、"posts/〇〇"の〇〇にはどんな値だろうと、ルーティング内の"posts/:id"と合致してしまう。なぜなら変数だから。
例えば、、、
"localhosut:8000/posts/abcdefz/"
このようなURLでも、ルーティングにデータ取得方法としてのget、URLに**/posts/が書かれていれば、否応なく"posts/:id"が合致してしまい、"posts#show"**が実行されてしまう。
このルーティングエラーに関する解説はネットでもいくらか散見したが、どれも言葉足らずな気がした。同じ状況に陥った人の一助になれるよう、ここに残します。