Ruby on Railsのaccepts_nested_attributes_forを使って、関連テーブルをまとめて登録する方法をご紹介します。
【Rails】accepts_nested_attributes_forで関連テーブルをAjaxで一括登録する方法
まず、登録したいモデルの親側にaccepts_nested_attributes_forメソッドを追加します。
今回は例としてdepartment(部署)とstaff(部員)を多対一の関係としてモデルを作成しています。
・app/models/department.rb
1 2 3 4 5 6 | class Department< ApplicationRecord has_many :staffs accepts_nested_attributes_for :staffs end |
・app/models/staff.rb
1 2 3 4 5 | class Staff< ApplicationRecord belongs_to department end |
これでモデルの準備は完了です。
Ajaxを使ってフォームから一括登録する
一括登録するために、以下のようなデータを用意します。実際に用意する時はユーザが入力した情報にあわせてJSでDOM生成する形になると思います。
以下のような関連テーブルにあわせて入れ子の形にして作る必要があります。
・app\views\departments\_department_index.html.erb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ... <form id="send_form"> <input name="department[name]" value="部署1"> <input name="department[address]" value="東京都"> <input name="department[representative]" value="テスト代表"> <input name="department[staffs_attributes][0][name]" value="テストスタッフ1"> <input name="department[staffs_attributes][0][tel]" value="08012345678"> <input name="department[staffs_attributes][0][email]" value="test1@email.com"> <input name="department[staffs_attributes][1][name]" value="テストスタッフ2"> <input name="department[staffs_attributes][1][tel]" value="09012345678"> <input name="department[staffs_attributes][1][email]" value="test2@email.com"> </form> ... |
用意したフォームの要素をURLクエリー用文字列にシリアライズし、Ajaxでサーバに送ります。
・app\assets\javascripts\departments.coffee
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ... $.ajax({ method : 'POST' url : self.create_department_url, data : $('#send_form').serialize(), }) .done(-> console.log 'success' ) .fail((xhr, textStatus, errorThrown) -> console.log 'failed' ) ... |
Ajaxで送られてきたデータをdepartment_paramsで整形することで、関連テーブルをまとめて一括登録することができます。
・app\controllers\departments_controller.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class DepartmentController < ApplicationController ... def create Department.create(department_params) end private def department_params params.require(:department).permit( :name, :address, :representative, staffs_attributes: [ :name, :tel, :email, ] ) end ... |
以上、accepts_nested_attributes_forで関連テーブルをまとめて登録する方法でした。