renderで指定したファイルがレンダリングする際にエラーになってしまう

renderで指定したファイルがレンダリングする際にエラーになってしまう現象
renderで指定したファイルがレンダリングする際にエラーになってしまうことがあり、ハマったのでこちらにまとめます。

以下のようなコードを記述していました。

[app/controllers/cooking_informations_controller.rb]

  def search_time      ①
    @fishes = Fish.all
    @cookings = Cooking.all
  end

  def search_calculate_cooking_time  ②
    @fishes = Fish.all
    @cookings = Cooking.all
    search_time_format = CookingSearchTimeForm.new(fish_kind: params[:fish_kind], cooking_name: params[:cooking_name])
    if search_time_format.save    ④
      @fish_kind = params[:fish_kind]
      @cooking_name = params[:cooking_name]
      @handle_pattern = search_time_format.handle_search
      @cooking_information = search_time_format.cooking_information_search
    else
      flash.now[:notice] = "検索フォームを全て入力してくだい"
      render :search_time
    end
  end

  def calculate_cooking_time   ③
    calculate_cooking_time_format = CalculateCookingTimeForm.new(let_foodstuff_capacity: params[:let_foodstuff_capacity], cookware_capacity: params[:cookware_capacity], count: params[:count])
    if calculate_cooking_time_format.save
      render template: "static_pages/top"
    else
      flash.now[:notice] = "計算フォームを全て入力してください"
      render :search_time
    end
  end
[app/forms/cooking_time_form.rb]

  include ActiveModel::Model
  include ActiveModel::Attributes
  
  attribute :fish_kind, :string
  attribute :cooking_name, :string

  validates :fish_kind, presence: true
  validates :cooking_name, presence: true

  def save
    invalid? ? false : true
  end

  def handle_search
    cooking_id = Cooking.find_by(name: cooking_name).id
    fish_id = Fish.find_by(kind: fish_kind).id
    handle_id = CookingInformation.find_by(cooking_id: cooking_id, fish_id: fish_id).handle_id
    Handle.find(handle_id).pattern
  end

  def cooking_information_search
    cooking_id = Cooking.find_by(name: cooking_name).id
    fish_id = Fish.find_by(kind: fish_kind).id
    CookingInformation.find_by(cooking_id: cooking_id, fish_id: fish_id)
  end
[app/forms/calculate_cooking_time_form.rb]

  include ActiveModel::Model
  include ActiveModel::Attributes
  
  attribute :let_foodstuff_capacity, :integer
  attribute :cookware_capacity, :integer
  attribute :count, :integer
  
  validates :let_foodstuff_capacity, presence: true
  validates :cookware_capacity, presence: true
  validates :count, presence: true
  
  def save
    invalid? ? false : true
  end
[app/views/cooking_informations/search_time.html.slim]

.search-wrapper
  .container
    .row.justify-content-md-center
      .col-md-auto.mt-5
        = render partial: 'search_time_form'
[app/views/cooking_informations/search_caluculate_cooking_time.html.slim]

.search-wrapper
  .container
    .row.justify-content-md-center
      .col-md-auto.mt-5
        = render partial: 'search_time_form'   ⑤
    .row.justify-content-md-center
      .col
       .mt-5.fs-3.cooking-list
         .cooking-information-title
           ' 料理名:
           = @cooking_name
           | (
           = @fish_kind
           | )<br>
           ' 捌き方:
           = @handle_pattern
         .cooking-information-overview.mt-4
           .d-inline-block
             = image_tag cooking_image_path(@cooking_information), size: '400x300', class: 'rounded-circle'
           .d-inline-block.float-end
             = form_with url: calculate_cooking_time_cooking_informations_path, local: true do |f|
               .form-group
                 = f.label :count, '調理する魚の数:'
                 = f.number_field :count, min: 1, placeholder: '料理する魚の数(必須)', class: 'calculate-fish-count-form text-center'
               .form-group
                 = f.label :let_foodstuff_capacity, '食材を寝かせられるキャパシティ:'
                 = f.number_field :let_foodstuff_capacity, min: 1, step: 0.5, placeholder: '匹数(必須)', class: 'calculate-cooking-capacity-form text-center'
               .form-group
                 = f.label :cookware_capacity, '調理機材のキャパシティ:'
                 = f.number_field :cookware_capacity, min: 1, step: 0.5, placeholder: '匹数(必須)', class: 'calculate-cooking-capacity-form text-center'
               = f.submit '合計の料理時間は?', class: 'btn btn-primary calculate-cooking-time-button'
           .d-flex.justify-content-center.mt-5#js-result-calculate-cooking-time
             ' 料理時間の合計:
             | ?<br>
             ' 捌く時間の合計:
             | ?<br>
             ' 調理時間の合計:
             | ?
         .cooking-information-details.mt-4
           .d-inline-block
             | 捌き方の動画
             .mt-3
               iframe width="400" height="300" src="#{FishHandleInformation.find_by(fish_id: @cooking_information.fish_id, handle_id: @cooking_information.handle_id).handle_url}"
           .d-inline-block.float-end
             | 料理のレシピサイト<br>
             .mt-5
               = link_to '調理レシピ', "#{@cooking_information.cooking_url}"
[app/views/cooking_informations/_search_time_form.html.slim]

= form_with url: search_calculate_cooking_time_cooking_informations_path, local: true do |f|
  .form-group
    = f.collection_select :fish_kind, @fishes, :kind, :kind, { include_blank: '魚の種類(必須)' }, {class: 'search_select_form'}
    = f.collection_select :cooking_name, @cookings, :name, :name, { include_blank: '料理の種類(必須)' }, {class: 'search_select_form'}
    = button_tag type: 'submit', class: 'btn btn-primary search_button' do
      i.fas.fa-search

最初に①のアクションにより以下のような画面がレンダリングされる。

Image from Gyazo

上記の画像の魚の種類と料理の種類を入力して検索すると、②のアクションにより以下のような画面がレンダリングされる。

Image from Gyazo

上記の画像の(調理する魚の数)と(食材を寝かせられるキャパシティ)と(調理機材のキャパシティ)を入力して検索すると、③のアクションの下記より、

render template: "static_pages/top"

下記のような画面がレンダリングされる。

Image from Gyazo

(調理する魚の数)と(食材を寝かせられるキャパシティ)と(調理機材のキャパシティ)のいずれかを入力しない場合は、④のバリデーションに引っかかり、以下の処理がされる。

flash.now[:notice] = "計算フォームを全て入力してください"
render :search_calculate_cooking_time

renderで[search_calculate_cooking_time]アクションを指定しているので、以下の画面がレンダリングされるのを期待していたが、

Image from Gyazo

実際は、以下のようなエラーになってしまう。

Image from Gyazo

これは、HTTPプロトコルはステートレスによる通信による為である。

Image from Gyazo

流れは以下のようになります。
上記の画面から(調理する魚の数)と(食材を寝かせられるキャパシティ)と(調理機材のキャパシティ)を入力してHTTPリクエストを送る。

サーバー側では、レンダリングにより③のアクションが動く。

バリデーションに引っかからない場合は、以下が処理される。

render template: "static_pages/top"

アプリケーションのトップページがレンダリングされる。

バリデーションに引っかかる場合は、以下が処理される。

render :search_calculate_cooking_time

上記記述により、[app/views/cooking_informations/search_caluculate_cooking_time.html.slim]をレンダリングするファイルに指定する。

[app/views/cooking_informations/search_caluculate_cooking_time.html.slim]の⑤の部分(以下参照)により、

= render partial: 'search_time_form'

[app/views/cooking_informations/_search_time_form.html.slim]がレンダリングするファイルに指定されているが、
このファイルの中には、

= form_with url: search_calculate_cooking_time_cooking_informations_path, local: true do |f|
  .form-group
    = f.collection_select :fish_kind, @fishes, :kind, :kind, { include_blank: '魚の種類(必須)' }, {class: 'search_select_form'}
    = f.collection_select :cooking_name, @cookings, :name, :name, { include_blank: '料理の種類(必須)' }, {class: 'search_select_form'}
    = button_tag type: 'submit', class: 'btn btn-primary search_button' do
      i.fas.fa-search

上記のように[@fishes]や[@cookings]などの配列が記載されているが、(調理する魚の数)と(食材を寝かせられるキャパシティ)と(調理機材のキャパシティ)を入力する際にHTTPリクエストを送るさいは、以下のアクションを通るため、

  def calculate_cooking_time
    calculate_cooking_time_format = CalculateCookingTimeForm.new(let_foodstuff_capacity: params[:let_foodstuff_capacity], cookware_capacity: params[:cookware_capacity], count: params[:count])
    if calculate_cooking_time_format.save
      render template: "static_pages/top"
    else
      flash.now[:notice] = "計算フォームを全て入力してください"
      render :search_calculate_cooking_time
    end
  end

[@fishes]や[@cookings]を取得していないので、エラーになる。
バリデーションに引っかからない際に、以下のレンダリングがエラーにならないのはトップページのビューファイルにインスタンス変数が記載されていない為である。

render template: "static_pages/top"

参考記事

collection_selectにインスタンス変数を渡すと、undefined method `map' for nil:NilClass が発生するエラー - Qiita