エラーの内容
送信フォームを押すと、画像のフォームが消えてしまう。
状況
フリマアプリのコピーアプリで、商品出品機能を実装中。
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の後にインスタンスを作成しないとフォームが消えてしまう。