フォームの一部を共通化

`new.html.erb`と`edit.html.erb`で以下のように`form_for`を使用し、データの保存、変更を行いたい！
`new.html.erb`と`edit.html.erb`で同じフォームを使用していたら、formの部分を丸ごとパーシャルにしておしまいなのですが・・・

現在、開発しているとこでは`new.html.erb`と`edit.html.erb`で使用しているフォームが一部異なるため、まるまる共通化できません。
そこで、合致している部分だけ共通化し、異なる部分は条件分岐で切り分けようということで、その方法を忘れないように記したいと思います。

まず、`new.html.erb`の方はこんな感じです。

```html:new.html.erb
<%= form_for(@user, :url => {:action => 'create'} ) do |f| %>
  <%= render :partial => 'error_message' %>
  <table>
    <tr>
      <td><%= f.label :ユーザーID %></td>
      <td><%= f.text_field :user_id %></td>
    </tr>
    <tr>
      <td><%= f.label :画像ID %></td>
      <td><%= f.text_field :photo_id %></td>
    </tr>
    <tr>
      <td><%= f.label :配信日 %></td>
      <td><%= f.text_field :open_date %></td>
    </tr>
    </table>
    <%= f.submit "登録" %>
<% end %>
```
`edit.html.erb`は以下の通りです。

```html:edit.html.erb
<%= form_for(@user, :url => {:action => 'update'} ) do |f| %>
  <%= render :partial => 'error_message' %>
  <table>
    <tr>
      <td><%= f.label :ユーザーID %></td>
      <td><%= f.text_field :user_id %></td>
    </tr>
    <tr>
      <td><%= f.label :画像ID %></td>
      <td><%= f.text_field :photo_id %></td>
    </tr>
    <tr>
      <td><%= f.label :配信日 %></td>
      <td><%= f.text_field :open_date %></td>
    </tr>
    <tr>
      <td><%= f.label :表示順位 %></td>
      <td><%= f.text_field :visible_order %></td>
    </tr>
    </table>
    <%= f.submit "更新" %>
<% end %>
```

```html:共通部分
<%= render :partial => 'error_message' %>
  <table>
    <tr>
      <td><%= f.label :ユーザーID %></td>
      <td><%= f.text_field :user_id %></td>
    </tr>
    <tr>
      <td><%= f.label :画像ID %></td>
      <td><%= f.text_field :photo_id %></td>
    </tr>
    <tr>
      <td><%= f.label :配信日 %></td>
      <td><%= f.text_field :open_date %></td>
    </tr>
```
切り分けたい部分は以下です。

```html:レイアウト1   
    <tr>
      <td><%= f.label :表示順位 %></td>
      <td><%= f.text_field :visible_order %></td>
    </tr>
    </table>
  <%= f.submit "更新" %>
<% end %>
```

```html:レイアウト2
    </table>
  <%= f.submit "登録" %>
<% end %>
```

#1. 現在いるURLを参照し切り分ける方法
まず、`_form.html.erb`を作成し、`request.path_info`で現在いるURLを参照し、そのURLによってレイアウトを切り分けます。
こんな感じです。

```html:_form.html.erb
<%= render :partial => 'error_message' %>
  <table>
    <tr>
      <td><%= f.label :ユーザーID %></td>
      <td><%= f.text_field :user_id %></td>
    </tr>
    <tr>
      <td><%= f.label :画像ID %></td>
      <td><%= f.text_field :photo_id %></td>
    </tr>
    <tr>
      <td><%= f.label :配信日 %></td>
      <td><%= f.text_field :open_date %></td>
    </tr>
  <% if request.path_info = edit_users_path %>
    <tr>
      <td><%= f.label :表示順位 %></td>
      <td><%= f.text_field :visible_order %></td>
    </tr>
    </table>
    <%= f.submit "更新" %>
  <% else %>
    </table>
    <%= f.submit "登録" %>
  <% end %>
```
```html:new.html.erb
<%= form_for(@user, :url => {:action => 'create'} ) do |f| %>
  <%= render :partial => 'form', :locals => {:f => f} %>
<% end %>
```

```html:edit.html.erb
<%= form_for(@user, :url => {:action => 'update'} ) do |f| %>
  <%= render :partial => 'form', :locals => {:f => f} %>
<% end %>
```
非常にすっきりしました。
`<% if request.path_info = edit_users_path %>`によって、editページでformが呼び出されたらレイアウト1を表示し、それ以外のページで表示されたら場合は`<% else %>`以下のレイアウト2が表示されます。
切り分けるページが2つと限られていたらこの方法でも対応できます。

#2. renderに引数を渡して切り分ける方法
`_form.html.erb`の方で、`<% if local_assigns[:edit_flag].present? %>`を使用し、partialの指定したローカル変数に値が入っているか否かを判別し切り分ける方法です。
この条件分岐をすることで、レイアウト1を使用したいページのhtmlに`render :partial => 'form' :locals = >{ :f => f, :edit_flag => true}`と定義するとどのページでもレイアウト1のフォームが適用されます。

`_form`は以下の通りです。

```html:_form.html.erb
<%= render :partial => 'error_message' %>
  <table>
    <tr>
      <td><%= f.label :ユーザーID %></td>
      <td><%= f.text_field :user_id %></td>
    </tr>
    <tr>
      <td><%= f.label :画像ID %></td>
      <td><%= f.text_field :photo_id %></td>
    </tr>
    <tr>
      <td><%= f.label :配信日 %></td>
      <td><%= f.text_field :open_date %></td>
    </tr>
  <% if local_assigns[:edit_flag].present? %>
    <tr>
      <td><%= f.label :表示順位 %></td>
      <td><%= f.text_field :visible_order %></td>
    </tr>
    </table>
    <%= f.submit "更新" %>
  <% else %>
    </table>
    <%= f.submit "登録" %>
  <% end %>
```

各ページのhtmlは以下の通りです。

```html:new.html.erb
<%= form_for(@user, :url => {:action => 'create'} ) do |f| %>
  <%= render :partial => 'form', :locals => {:f => f} %>
<% end %>
```

```html:edit.erb
<%= form_for(@pickup_client, :url => {:action => 'update'}) do |f| %>
  <%= render :partial => 'form', :locals => {:f => f, :edit_flag => true} %>
<% end %>
```

この切り分けのメリットとしては、各ページで使いたいレイアウト用にrenderの引数を定義すれば良いので、partialをいじる必要がなく、保守性が高いという点にあります。