「新規作成画面と編集画面」のようにform_with等を使用してデータの登録、編集を実装したい。
そこで、共通している入力フォームはパーシャルにしてしまおう!!と考えました。
ですが、form_with内には登録ボタンや更新ボタンなど部分的に違う箇所もあるので全部共通化はできません。
その際実装した内容を記述して残しておきます。
実装時のポイント
・同じ箇所は共通化する
・違う箇所は条件分岐で表示の切り替え
・render時に引数を渡す
この3点を行いました。
最初の状態はこんな感じ。(フォーム内容は例になります)
(新規作成画面)
<%= form_with model: @post, url: confirm_posts_path, html: { method: :post }, local: true do |f| %>
<div class="sample">
<div>
<%= f.label :画像 %>
<%= f.file_field :image, id: "post_img" %>
<%= f.hidden_field :image_cache %>
</div>
<div>
<%= f.label :名前 %>
<%= f.text_field :user_name %>
</div>
<div>
<%= f.label :犬の名前 %>
<%= f.text_field :dog_name %>
</div>
</div>
<%= f.submit "確認画面へ" %>
<% end %>
(編集画面)
<%= form_with model: @post, local: true do |f| %>
<div class="sample">
<div>
<%= f.label :画像 %>
<%= f.file_field :image, id: "post_img" %>
<%= f.hidden_field :image_cache %>
</div>
<div>
<%= f.label :名前 %>
<%= f.text_field :user_name %>
</div>
</div>
<%= f.submit "更新" %>
<% end %>
(共通箇所)
<div class="sample">
<div>
<%= f.label :画像 %>
<%= f.file_field :image, id: "post_img" %>
<%= f.hidden_field :image_cache %>
</div>
<div>
<%= f.label :名前 %>
<%= f.text_field :user_name %>
</div>
(切り分けたい箇所)
<div>
<%= f.label :犬の名前 %>
<%= f.text_field :dog_name %>
</div>
</div>
<%= f.submit "確認画面へ" %>
</div>
<%= f.submit "更新" %>
部分テンプレートの作成
_post_form.html.erbに <% if local_assigns[:edit_flag].present? %>と記述することでpartialの指定したローカル変数に値が入っているか判別し分岐させる。
_post_form.html.erbを新しく作成して以下のように記述します。
<div class="sample">
<div>
<%= f.label :画像 %>
<%= f.file_field :image, id: "post_img" %>
<%= f.hidden_field :image_cache %>
</div>
<div>
<%= f.label :名前 %>
<%= f.text_field :user_name %>
</div>
<% if local_assigns[:edit_flag].present? %>
<div>
<%= f.submit "更新" %>
<% else %>
<div>
<%= f.label :犬の名前 %>
<%= f.text_field :dog_name %>
</div>
</div>
<%= f.submit "確認画面へ" %>
<% end %>
</div>
各HTMLは以下になります。
<%= form_with model: @post, url: confirm_posts_path, html: { method: :post }, local: true do |f| %>
<%= render :partial => 'post_form', :locals => {:f => f} %>
<% end %>
<%= form_with model: @post, local: true do |f| %>
<%= render :partial => 'post_form', :locals => {:f => f, :edit_flag => true} %>
<% end %>
かなりスッキリさせることができました。
使用したいページでrenderの引数を定義すれば良いだけなので簡単です。