本日学習中にこのようなエラーが発生しました!!
原因を調べてみたところ、これはRailsを使っているときによく起きる「ルートのけんか(競合)」というエラーです。
状況を整理すると、
僕が操作の中で開きたかったのは、「/users/sign_up」、
つまるところログインページです!
しかしRailsの中では、
routes.rbに
resources :users
と書いてあるので、「/users/○○」にアクセスがあると
UsersControllerのshowアクションが動くようになっています。
(○○の部分には「ID(数字)」が入る想定)
Railsは「sign_up」も文字列だから「IDかな?」と勘違いして、
User.find("sign_up") を実行してしまいました。
でもそんなユーザーはいないのでエラーになった、という流れです。
■ ⚔️ どうして起きたの?
「devise_for :users」と「resources :users」が両方あるからです。
- devise_for :users → サインアップやログインなどのURLを作る
(例: /users/sign_up, /users/sign_in) - resources :users → ユーザー詳細ページ(/users/:id)を作る
どちらも「/users/なんとか」を使うので、Railsが混乱してしまうわけです。
■ 🧭 解決策(初心者向け)
① ルートの順番を変える(これが一番簡単)
config/routes.rbの中をこの順番にします:
devise_for :users ← これを先に書く!
resources :users, only: [:show] ← これを後に書く!
Railsは上から順にルートを探すので、
「/users/sign_up」は先にdeviseが見つけてくれます。
② 「:id」は数字だけOKにする
次のようにすれば、「sign_up」はID扱いされません:
resources :users, only: [:show], constraints: { id: /\d+/ }
③ URLを変える(別名にする)
ユーザー詳細のURLを別の名前に変える方法もあります:
resources :profiles, only: [:show], controller: 'users'
これで「/profiles/1」というURLになります。
■ 🧩 つまりこういうこと
Railsは上から順にルールを読んでいく。
だから順番を変えるだけで解決できる!
修正前:
/users/sign_up → UsersController#show (勘違い!)
修正後:
/users/sign_up → Devise(正解!)
/users/1 → UsersController#show(正解!)
■ 💡 まとめ
・原因:Railsが「sign_up」をIDだと勘違いした
・理由:「devise_for」と「resources」がケンカしてた
・解決:ルートの順番を変える or 数字制限をつける
・結果:サインアップとユーザー詳細が正しく分かれる
Railsは「上から順番に読む」というシンプルなルールを踏まえておかないと、
混乱してしまい今回のようなエラーが発生してしまうということです!!
