Rails4 の form_for は multipart: true を省略可能


5 Uploading Files
http://guides.rubyonrails.org/form_helpers.html#uploading-files

ということらしい。
知らなかったので試してみた。

適当なプロジェクトを作成。

```shell-session
% rails new example --skip-bundle && cd example && bundle install --path=vendor/bundle
```

環境は以下。

```shell-session
% ./bin/rake about
About your application's environment
Ruby version              2.1.3-p242 (x86_64-linux)
RubyGems version          2.2.2
Rack version              1.5
Rails version             4.1.8
・・・
```

適当な scaffold を作成。

```shell-session
% bundle exec rails g scaffold post title:string body:text
```

生成された `app/views/posts/_form.html.erb` は以下のような内容。

```erb
<%= form_for(@post) do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @post.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :body %><br>
    <%= f.text_area :body %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
```

この状態でブラウザからアクセスした際に生成された HTML は以下のようなもの。
当然だけど `form` タグには `enctype="multipart/form-data"` は指定されていない。

```html
<!DOCTYPE html>
<html>
<head>
  <title>Example</title>
  <link data-turbolinks-track="true" href="/assets/posts.css?body=1" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/assets/scaffolds.css?body=1" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/assets/application.css?body=1" media="all" rel="stylesheet" />
  <script data-turbolinks-track="true" src="/assets/jquery.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery_ujs.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/turbolinks.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/posts.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/application.js?body=1"></script>
  <meta content="authenticity_token" name="csrf-param" />
<meta content="wvtYCGLda3V5pS0q0kuXG4rqHz4kVsCAlQW8BFZI91M=" name="csrf-token" />
</head>
<body>

<h1>New post</h1>

<form accept-charset="UTF-8" action="/posts" class="new_post" id="new_post" method="post"><div style="display:none"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="wvtYCGLda3V5pS0q0kuXG4rqHz4kVsCAlQW8BFZI91M=" /></div>

  <div class="field">
    <label for="post_title">Title</label><br>
    <input id="post_title" name="post[title]" type="text" />
  </div>
  <div class="field">
    <label for="post_body">Body</label><br>
    <textarea id="post_body" name="post[body]">
</textarea>
  </div>
  <div class="actions">
    <input name="commit" type="submit" value="Create Post" />
  </div>
</form>

<a href="/posts">Back</a>


</body>
</html>
```

`app/views/posts/_form.html.erb` に以下のように `file_field` を追加してみる。

```erb
  <div class="field">
    <%= f.label :image %><br>
    <%= f.file_field :image %>
  </div>
```

この状態で再度ブラウザからアクセスして生成された HTML は以下。

```html
<!DOCTYPE html>
<html>
<head>
  <title>Example</title>
  <link data-turbolinks-track="true" href="/assets/posts.css?body=1" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/assets/scaffolds.css?body=1" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/assets/application.css?body=1" media="all" rel="stylesheet" />
  <script data-turbolinks-track="true" src="/assets/jquery.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery_ujs.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/turbolinks.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/posts.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/application.js?body=1"></script>
  <meta content="authenticity_token" name="csrf-param" />
<meta content="wvtYCGLda3V5pS0q0kuXG4rqHz4kVsCAlQW8BFZI91M=" name="csrf-token" />
</head>
<body>

<h1>New post</h1>

<form accept-charset="UTF-8" action="/posts" class="new_post" enctype="multipart/form-data" id="new_post" method="post"><div style="display:none"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="wvtYCGLda3V5pS0q0kuXG4rqHz4kVsCAlQW8BFZI91M=" /></div>

  <div class="field">
    <label for="post_title">Title</label><br>
    <input id="post_title" name="post[title]" type="text" />
  </div>
  <div class="field">
    <label for="post_body">Body</label><br>
    <textarea id="post_body" name="post[body]">
</textarea>
  </div>
  <div class="field">
    <label for="post_image">Image</label><br>
    <input id="post_image" name="post[image]" type="file" />
  </div>
  <div class="actions">
    <input name="commit" type="submit" value="Create Post" />
  </div>
</form>

<a href="/posts">Back</a>


</body>
</html>
```

ちゃんと `form` タグに `enctype="multipart/form-data"` が指定されている。

いつからこういう挙動になったのかまでは確認していないが、少なくとも Rails 4.1 では `form_for` の場合はブロック内で `file_field` を使っている場合、いちいち `multipart: true` を指定しなくてもいいみたいだ。

**2016.06.20 追記:**

コメント欄で教えて頂いたが、3.1 からこの挙動だった模様。

## 参考

form_tagでファイルアップロード時はmultipart:trueを省略しない[Rails4] - source
http://source.hatenadiary.jp/entry/2014/03/21/143914