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を使用せずにネストされた属性を含むフォームを作成する際の参考になれば幸いです。