エラーの内容
送信フォームを押すと、画像のフォームが消えてしまう。
状況
フリマアプリのコピーアプリで、商品出品機能を実装中。
itemモデルのデータを登録できるようにフォームを作成し、バリデーションを設定した。
その後、商品画像であるimageモデルのデータも同時に登録できるようフォームを作成した。
データが登録されなかった場合は、元の画面に遷移するようにコントローラーにrender :newを記述。
バリデーションの確認のため、フォームを空白にして送信したところ、renderによってページが遷移したが、
画像の投稿フォームのみ消えてしまうという挙動を示した。
ブラウザの画像
https://gyazo.com/c0ba763dcc41e6b4d2fdbc8246208a32
遷移後のブラウザの画像
https://gyazo.com/bd1b0e347b3156486149240e7479af98
コード
class ItemsController < ApplicationController
  def index
  end
  def new
    @item = Item.new
    @item.images.new
  end
  
  def create
    @item = Item.new(item_params)
    if @item.save
      redirect_to root_path
    else
      render :new
    end
  end
  private  
  def item_params
    params.require(:item).permit(:name, :description, :brand, :condition, :status, :shipping_costs, :shipping_from, :shipping_date, :price, images_attributes: [:src])
  end
end
.sell-items__top
  .sell-items__top__container
    = form_with(model: @item, local: true) do |f|
      %ul
        %li.sell-items__top__container__list
          = f.text_field :name, placeholder: "商品名"
        %li.sell-items__top__container__list#image-box
          = f.fields_for :images do |image|
            %div{data: {index: image.index}, class: 'js-file_group'}
              商品画像
              = image.file_field :src, class: 'js-file'
              %br/
              %span.js-remove 削除
        %li.sell-items__top__container__list
          = f.text_area :description, placeholder: "説明文", rows: "10"
        %li.sell-items__top__container__list
          = f.text_field :brand, placeholder: "ブランド"
        %li.sell-items__top__container__list
          = f.text_field :condition, placeholder: "状態"
        %li.sell-items__top__container__list
          = f.text_field :shipping_costs, placeholder: "送料"
        %li.sell-items__top__container__list
          = f.text_field :shipping_from, placeholder: "発送元"
        %li.sell-items__top__container__list
          = f.text_field :shipping_date, placeholder: "発送日"
        %li.sell-items__top__container__list
          = f.text_field :price, placeholder: "価格"
        %li.sell-items__top__container__list
          = f.submit "SEND"
解決策
createアクションに追記。
  def create
    @item = Item.new(item_params)
    if @item.save
      redirect_to root_path
    else
      @item.images.new ←
      render :new
    end
  end
原因
renderによって遷移した先の画面は、items/newに見えるが、パスを確認するとitems/createであることがわかる。
つまり、見かけはnewアクションだが、中身はcreateアクションのビューである。
そのため、createアクションでelseの後にインスタンスを作成しないとフォームが消えてしまう。