Railsフォームでfields_for
を使用せずにネストされた属性を扱う方法
Railsのfields_for
メソッドは、フォーム内でネストされた属性を簡単に扱うための便利なヘルパーです。しかし、特定の状況や要件によりfields_for
を使えない場合があります。この記事では、fields_for
を使用せずにネストされた属性をフォームで扱う方法を紹介します。
前提条件
hospitalsテーブル
、business_daysテーブル
、hospital_business_daysテーブル
、hospital_business_hoursテーブル
がある。
hospitalsテーブル
とbusiness_daysテーブル
はhospital_business_daysテーブル
を中間テーブルとして多対多。hospital_business_daysテーブル
とhospital_business_hoursテーブル
は1対多の関係である。
基本的な考え方
fields_for
を使用せずにネストされた属性を扱う主な方法は、フォームのinput
フィールドのname
属性を手動で設定することです。これにより、コントローラに正しくネストされたパラメータを送信することができます。
例として、hospital
オブジェクトに関連するhospital_business_days
とその中のhospital_business_hours
というネストされた属性を扱います。
具体的なコード例
以下は、hospital
オブジェクトのアップデート用フォームで、hospital_business_days_attributes
とその中のhospital_business_hours_attributes
を送信するための入力フィールドの例です。
<input type="hidden" name="hospital[hospital_business_days_attributes][<%= index %>][business_day_id]" value="<%= business_day.id %>">
<td>
<input type="time" name="hospital[hospital_business_days_attributes][<%= index %>][hospital_business_hours_attributes][0][open_time]" value="<%= hospital_business_hour.open_time&.strftime('%H:%M') %>">
</td>
<td>
<input type="time" name="hospital[hospital_business_days_attributes][<%= index %>][hospital_business_hours_attributes][0][close_time]" value="<%= hospital_business_hour.close_time&.strftime('%H:%M') %>">
</td>
このコードでは、index
は各hospital_business_days
オブジェクトのインデックスを示し、business_day.id
はそのbusiness_day
のIDです。hospital_business_hour.open_time
とhospital_business_hour.close_time
はそれぞれ開始時間と終了時間を示します。
Strong Parametersの設定
フォームから送信されたネストされた属性をコントローラで正しく扱うためには、Strong Parametersを適切に設定する必要があります。以下は、hospital
オブジェクトのパラメータを許可するための例です。
params.require(:hospital).permit(hospital_business_days_attributes: [:business_day_id, hospital_business_hours_attributes: [:open_time, :close_time]])
まとめ
fields_for
を使用せずにネストされた属性を扱う方法は、フォームのinput
フィールドのname
属性を適切に設定することで実現できます。この方法は、特定のシナリオやカスタムフォームの要件に応じて役立ちます。ただし、Strong Parametersの設定には注意が必要です。
この記事が、fields_for
を使用せずにネストされた属性を含むフォームを作成する際の参考になれば幸いです。