🧯

【rails】NoMethodError・undefined method `xxxx_path' for でハマった話

2023/01/09に公開約2,300字

ポートフォリオ作成中にハマった話をします。

始めに書いてしまいますが、エラーの原因は
「フォームに渡しているモデルと設定されているパスの構造が違っていたから」
でした。

もっと言うと、「モデルの構造がおかしかったから」。


simple_formでフォームを設置したところ、以下のようなエラーが発生しました。

エラー文
NoMethodError in FundRestaurants#new

undefined method `fund_restaurants_path' for #<#<Class:0x0000ff...

「fund_restaurants_pathというパスはありません」って言われてる。。。なんで?

以下で詳しく見ていきます。


状況確認

routes.rbを確認します。

該当箇所のルーティング

routes.rb
resources :rooms, only: [:new, :create, :show], param: :token do
  resources :fund_restaurants, only: [:show, :new, :create, :destroy]
end

fund_restaurantsへのルーティングは、roomsをネストさせた中に作成していました
理由:roomごとに、アクセスできるfund_restaurant(飲食店基本情報)を制限するため

下記コマンドでパスを確認
rails routes | grep restaurant

ターミナル
                room_fund_restaurants POST   /rooms/:room_token/fund_restaurants(.:format)                             fund_restaurants#create
             new_room_fund_restaurant GET    /rooms/:room_token/fund_restaurants/new(.:format)                         fund_restaurants#new
                 room_fund_restaurant GET    /rooms/:room_token/fund_restaurants/:id(.:format)                         fund_restaurants#show
                                      DELETE /rooms/:room_token/fund_restaurants/:id(.:format)                         fund_restaurants#destroy

エラーの原因

フォームに渡しているモデルと設定されているパスの構造が違っていたから

フォームで作られたパス: fund_restaurants (_path)
rails routesで確認されたパス: room_fund_restaurants(上記コードブロックの1行目)

違いますね。。。

原因を詳しく記すと、以下となります

routesがネストされていたのに、モデルがそうなっておらず、モデルのインスタンスを元にフォームで作成されたパスと、実際のパスが違っていたため

フォームに渡されていたインスタンス変数を追っていきます。

フォームのコード
<%= simple_form_for @restaurant do |f| %>
# 省略
app/controllers/fund_restaurants_controller.rb
# 該当箇所のみ記述
def new
  @restaurant = FundRestaurant.new    # ここがRoom::FundRestaurant.newでないとダメ

room_fund_restaurants_pathを作ってほしいのに、FundRestaurant.new をフォームに渡していました。それはうまくいきませんね。

解決策

モデルを作り直した。rails g modelをやり直した

ターミナル
rails g model Room::FundRestaurant
修正後 app/controllers/fund_restaurants_controller.rb
# 該当箇所のみ記述
def new
  @restaurant = Room::FundRestaurant.new

さいごに

このエラーで3時間ほど詰まっていました。
ルーティングとモデルの構造を一致させるということがわかっていなかったこと、
それとrailsのフォームがあまり理解できていなかったことが原因。

今回のエラーのおかげで、曖昧だったrailsのフォームの理解が進んだ気がします。

どなたかのお役に立てれば幸いです!

Discussion

ログインするとコメントできます