ガラシのパルプンテ頼み

地方産限界エンジニアのグローバル独り言

【5分くらいでわかる】formからネストしたハッシュの配列を送信する方法 | Rails入門

入門といいつつ今回は少し踏み込んだフォームの使い方について。 実務の要件ではform_withの枠組みから外れて、送るパラメータの構造を設計しなければならない場面に直面することもあります。 今回はそんな時に覚えておくとちょっと役立つかもしれないテクニックを3つほど紹介していきます。 この記事を最後まで読むことで、下記のようなパラメータを自在に設計できるようになります。

users: [
  {
   id: 10, name: "山田太郎", email: "test@email.com", phone_number: '024-111-11',
   action_histoires: [
    {id: 10, action_datetime: "2022-05-13T00:00:00", description: "外出"},
    {id: 20, action_datetime: "2022-05-13T00:00:00", description: "直帰"},
    {id: nil, action_datetime: "2022-05-13T00:00:00", description: "時間休 13:00~"},
   ],
  },
  {
   id: 20, name: "山田太郎", email: "test@email.com", phone_number: '024-111-11',
   action_histoires: [
    {id: 30, action_datetime: "2022-05-13T00:00:00", description: "外出"},
    {id: nil, action_datetime: "2022-05-13T00:00:00", description: "直帰"},
    {id: nil, action_datetime: "2022-05-13T00:00:00", description: "直帰"},
   ],
  },
]

この例はユーザーとそれに紐づくユーザーの行動履歴をネスト形式で送るという想定です。 usersという配列の中に各ユーザーの情報がハッシュとして格納されており、その中で更に関連する行動履歴をaction_historiesというハッシュの配列として持ち合わせています。このような構造のparamsを作るための方法を以下の順で追っていこうと思います。

  1. フォームからデータをハッシュ形式で送る方法
  2. フォームからデータを配列形式で送る方法
  3. フォームからデータをハッシュの配列形式で送る方法

データをハッシュ形式で送る

htmlのinputでname属性に user[name] のように指定すると、指定したパラメーター名でハッシュが作成されます。(ブラケット内のワードをキーに、inputに入力された値がバリューになる)

Rails(viewファイル)

<%= form.text_field 'user[name]' %> 
<%= form.email_field 'user[email]' %> 

form_withにモデルのインスタンスが指定されていれば以下と同義です

<%= form_with(model: User.new, local: true) do |form| %> 
    <%= form.text_field :name %> 
    <%= form.email_field :email %> 
<% end %>

form_withにmodelオプションが指定されている場合、formヘルパーの第一引数にモデルが持つ属性をシンボルで指定することが可能です。 このように指定した場合、復元されたhtmlでは モデル名[属性名] の形式のname属性がinputタグに自動でセットされます。

復元されるhtml

<input type="text" name="user[name]" value="山田太郎" >
<input type="email" name="user[email]" value="yamada@email.com" >

送信されるparams

user => {
  name: '山田太郎',
  email: 'yamada@email.com'
}

データを配列形式で送る

htmlのinputでname属性に user[] のように指定すると、同じnameを持つinput valueの配列が作成されます。

Rails(viewファイル)

<%= form.text_field 'user[]' %>
<%= form.email_field 'user[]' %> 

復元されるhtml

<input type="text" name="user[]" value="山田太郎" >
<input type="email" name="user[]" value="yamada@email.com" >

送信されるparams

user => ['山田太郎', 'yamada@email.com']

データをハッシュの配列形式で送る

上記二つを合わせるイメージ。htmlのinputでname属性に users[][name]のように指定すると、usersというキーに配列が作成され、その配列の中に複数のハッシュが内包される構造を作ることが可能です。

Rails(viewファイル)

<%= form.text_field 'users[][name]' %>
<%= form.text_field 'users[][email]' %>

復元されるhtml

<input type="text" name="users[][name]" value="山田太郎" >
<input type="email" name="user[][email]" value="yamada@email.com" >
<input type="text" name="users[][name]" value="佐藤次郎" >
<input type="email" name="user[][email]" value="sato@email.com" >

送信されるparams

users => [
    { name: '山田太郎', email: 'yamada@email.com' },
    { name: '佐藤次郎, email: 'sato@email.com' },
]