(Rails) form_with modelではなくform_with urlを使いこなす
状況
投稿機能を作った際にcontrollerの中でindexとcreateの2つの部分でmodel名.newが使われていた。
また、全てのviewのアクションに対して、model名.newを用意するのが面倒である(before_action等を使えば防げるが...)
これは「rbの基本として、重複は避けるとある。」に反すると思い、回避できるのかを試してみた。
補足
indexのmodel名.newは「この箱に入れてください」という仮の箱を用意し、
createのmodel名.newは「仮の箱から取り出して正式な箱に入れてください」という感じ
結論
<%=form_with model:%>と<%=form_with url:%>を使い分けることで実現する。推奨ではない。
詳細
<%=form_with model:%>と<%=form_with url:%>の差
イメージとしてはもともとmodelの型(値を入れる箱)を作るか作らないかの差
そもそも <%=form_with model:%>と<%=form_with url:%>の違いはdbに保存するかどうかである。 簡単に言うとdbに保存する時に分かりやすくするかの違いである。
また、違いを別の言い方をすると、情報を送った時に2重のハッシュにするかどうかである。
投稿フォーム
view
# ココに<%=form_with ...%>が入る #model or url <%=f.text_field :name%> <%=f.submit "send"%>
<%=form_with model:%>の場合
出力結果
Parameters: {"authenticity_token"=>"[FILTERED]", "newname"=>{"name"=>"model"}, "commit"=>"send"} # 2つめの"newname"=>{"name"=>"model"}に注目
<%=form_with url:%>の場合
出力結果
Parameters: {"authenticity_token"=>"[FILTERED]", "name"=>"url", "commit"=>"send"} # 2つめの"name"=>"url" に注目
nameの部分が違うことがわかる
この時、<%=form_with url:%>の方はコントローラーのcreate以外でnewを呼び出す必要がない。➡重複しない
この際、アクションのcreateで用いるparams部分で注意が必要であり、
<%=form_with model:%>の場合
params.require(:newname)permit(:name)
<%=form_with url:%>の場合
params.permit(:name)
となる。 これはrequire部分で、2つ目のハッシュを指定するためである。
まとめ
controller内のmodel.newの重複を防ぐことを試していた。
<%=form_with url:%>を用いることで重複を防ぎいちいちmodel名.newを作成するのを防いだ。
この時、paramsに気を付けないとエラーとなる。