Sooey

2017-07-20 00:23:28 +0900

Rails 5.1の新しいform_withヘルパーはINPUT要素にid属性を設定しない

Rails 5.1で新たに導入された form_with ヘルパーは、これまでの form_for ヘルパーと違って、そのフォームオブジェクトを利用して生成されるDOM要素にid属性やclass属性をできるだけ付けないように設計されているようだ。

したがって、従来の form_for ヘルパーによって以下のようなHTMLが生成されていた場合に、

<label for="title_genre">作品ジャンル</label>
<input type="text" id="title_genre" value="...">

Capybara を使った feature spec 内で、以下のようにLABEL要素とINPUT要素のfor/id属性値による紐付けを利用して、

fill_in '作品ジャンル', with: 'ホラー'

のように指定していた箇所の実行が Capybara::ElementNotFound: Unable to find field "作品ジャンル" で失敗するようになる。

これを回避するためには、新しい form_with ヘルパーのフォームオブジェクトを利用してDOM要素を生成する際に、以下のように明示的にid属性値を指定する必要がある。

<%= form_with(...) do |form| %>
  <%= form.label(:genre) %>
  <%= form.text_field(:genre, id: :title_genre) %>
<% end %>

このあたりの挙動についてはAPIリファレンスのform_withの項目で詳しく解説されている。

また、以下のように label ヘルパーをブロックを渡す形で利用している場合には、生成されるLABEL要素にfor属性が設定される一方でブロック内のINPUT要素などにはid属性値が自動設定されないため、意図した動作(「確認しました」の部分をクリックするとチェックボックスが切り替わる)にならない場合がある。

<%= form.label(:confirmation) do %>
  <%= form.check_box(:confirmation) %> 確認しました
<%= end %>

これを解消するには、今のところ for 属性値を設定しないことを label ヘルパーで明示する必要があるようだ。

<%= form.label(:confirmation, for: nil) do %>
  <%= form.check_box(:confirmation) %> 確認しました
<%= end %>