質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

2回答

619閲覧

undefined method `id' for nil:NilClass

Engineer_traine

総合スコア17

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/07/19 01:59

編集2021/07/20 01:15

前提・実現したいこと

現在railsの学習でユーザーが部屋を登録したり予約できるといった機能の作成を行なっています。
しかし作成をしている途中でタイトルのようなエラーが発生してしましました。
具体的には部屋を登録する(greenhouseモデル)、部屋を予約する(reserverモデル)を1:1で紐づけを行い、部屋の登録ページから予約ページに遷移できるようリンクを用意し予約するための項目を入力し最後予約するボタンでdbに保存される状態をつくりました。
予約完了ボタンを押下した際に項目を全て入力した際のcontrollerのcreateアクションは正常通りに作動してくれるのですが項目を空欄した際に本来出るはずのバリデーション、エラーメッセージが出ません。
どなたかアドバイス等よろしくお願いします。

発生している問題・エラーメッセージ

NoMethodError in Reservers#create undefined method `id' for nil:NilClass

該当のソースコード

rails

1<h3>新規予約</h3> 2   3  <%= render "shared/error", obj: @reserver %> 4 5 <%= form_for @reserver do |f| %> 6 <%= f.hidden_field :user_id, value: current_user.id %> 7 <%= f.hidden_field :greenhouse_id, value: @greenhouse.id %> 8 <table class = "reserver_table" > 9 <tr> 10 <th>サンプルイメージ</th> 11 <td class = "room_sample"> 12 <%= image_tag @reserver.greenhouse.image %> 13 </td> 14 </tr> 15 16 <tr> 17 <th>料金</th> 18 <td><%= @reserver.greenhouse.price %>円/日</td> 19 </tr> 20 21 <tr> 22 <th><%= f.label :開始日 %></th> 23 <td><%= f.date_field :start, class:"start-content" %></td> 24 </tr> 25 26 <tr> 27 <th><%= f.label :終了日 %></th> 28 <td><%= f.date_field :end, class:"end-content" %></td> 29 </tr> 30 31 <tr> 32 <th><%= f.label :人数 %></th> 33 <td><%= f.number_field :number, class:"number-content" %></td> 34 </tr> 35 </table> 36 <div> 37 <ul> 38 <li><%= f.submit "予約を完了する" %></li> 39 </ul> 40 </div> 41 <% end %> 42   43 <div> 44 <ul> 45 <li><%= link_to "予約一覧に戻る", :reservers %></li> 46 </ul> 47 </div>

rails

1class ReserversController < ApplicationController 2 def index 3 @reservers = Reserver.all 4 end 5 6 def new 7 @reserver = Reserver.new 8 @greenhouse = Greenhouse.find(params[:format]) 9 end 10 11 def create 12 @reserver = Reserver.new(params.require(:reserver).permit(:start, :end, :number, :total, :user_id, :greenhouse_id)) 13 if @reserver.save 14 flash[:notice] = "新規予約をしました" 15 redirect_to action: :index 16 else 17 render :new 18 end 19 end 20 21 def show 22 @reserver = Reserver.find(params[:id]) 23 end 24 25 def edit 26 @reserver = Reserver.find(params[:id]) 27 end 28 29 def update 30 @reserver = Reserver.find(params[:id]) 31 if @reserver.update(params.require(:reserver).permit(:start, :end, :number, :total, :user_id, :greenhouse_id)) 32 flash[:notice] = "投稿を更新しました" 33 redirect_to :reservers 34 else 35 render "edit" 36 end 37 end 38 39 def destroy 40 @reserver = Reserver.find(params[:id]) 41 @reserver.destroy 42 flash[:notice] = "投稿を削除しました" 43 redirect_to :reservers 44 end 45end

試したこと

binding_pryでデータがうけたされているかの確認を行なった所しっかり渡せているように見えますが結果は以下のようでした。
イメージ説明

補足情報(FW/ツールのバージョンなど)

aws cloud9
rails 6.1

追記:
またnewアクションの新規作成画面で本来ならurlがreservers/new/1になるはずが
reserever/new.1になっていることも原因の一つでしょうか?
気になりましたので情報として追加させていただきます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

controllerのnewの箇所に@reserver.greenhouseを定義し、createの箇所のelseの処理のfind_byをfindに変更することで解決できました。

投稿2021/07/20 04:18

Engineer_traine

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

createに失敗して、new を renderする前に @greenhouse を設定してください

投稿2021/07/19 03:11

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Engineer_traine

2021/07/19 04:36

def create @reserver = Reserver.new(params.require(:reserver).permit(:start, :end, :number, :total, :user_id, :greenhouse_id)) if @reserver.save flash[:notice] = "新規予約をしました" redirect_to action: :index else @greenhouse = Greenhouse.find(params[:id]) render :new end end このようにするということでしょうか? この状態で起動するとCouldn't find Greenhouse without an ID というようなエラーが発生してしまいます。
winterboum

2021/07/19 07:50

それは Reserver の id では無いのでしょう。 eiitのviewから 送ってparamsに入れるか 今のparamsで入手したデータから手に入れるかしてください そもそも、どの Greenhouse を予約するのかという情報がないとおかしい
Engineer_traine

2021/07/19 11:37

後者の方で進めていきたいと考えていますが、手に入れ方がイマイチわかりません。 @greenhouse = @reserver.find(params[:greenhouse_id]) このような記述でインスタンス変数にgreenhouseのidを入れるのでしょうか? 情弱で申し訳ないです。
winterboum

2021/07/19 11:54

viewには渡っているのですから、そこで hidden_field で設定すれば良いです。 あれ? <%= f.hidden_field :greenhouse_id, value: @greenhouse.id %> もう有るじゃない。 これを使ってください
Engineer_traine

2021/07/20 01:23 編集

@greenhouse = Reserver.find_by(greenhouse_id: params[:reserver][:greenhouse_id]) をelse処理に追加してhidden_fieldを受け取ったところ解決し一度エラーメッセージを表示できたのですかトップに戻って再度同じ動作をしたところ NoMethodError in Reservers#new undefined method `image' for nil:NilClass <%= image_tag @reserver.greenhouse.image %>と表示されました。 controllerのnewの@reserverの定義が間違っていると思いますが何かアドバイスありませんでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問