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_with is not assigning id's to inputs · Issue #29450 · rails/rails
- Provide form_with as a new alternative to form_for/form_tag · Issue #25197 · rails/rails
したがって、従来の 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 %>