ひとつのフォームの中で複数のフィールドの登録をまとめて行いたいことがあります。そんなときに便利な方法を紹介します。
has_many関連の子レコードをまとめて登録出来るようになります。
キーワードは「accepts_nested_attributes_for」と「fields_for」です。
入れ子のフォームを扱うための下準備
テーブルをまとめて登録するために入れ子のフォームを作成することになります。それを可能にするためにaccepts_nested_attributes_for
というメソッドを使いましょう。
今回はteamsテーブルとmembersテーブルで話を進めたいと思います。
以下のような関係となります。
app/models/team.rb
class Team < ActiveRecord::Base
has_many :members
end
app/models/members.rb
class Member < ActiveRecord::Base
belongs_to :team
end
それではaccepts_nested_attributes_for
の設定を行いますが、設定は簡単です。
以下のようにteam.rbに追記するだけです。
app/models/team.rb
class Team < ActiveRecord::Base
has_many :members
accepts_nested_attributes_for :members #この行を追加
end
実際にフォームを使って登録する
app/controller/teams_controlelr.rb
class TeamsController < ApplicationController
def new
@team = Team.new
@team.members.build
end
end
以下のように、fields_forを使ってフォームの中に入れ子を作ることが出来ます。
views/groups/new.html.haml
.row.form
%p= '新規グループ作成'
.col-lg-8
= form_for @team do |f|
= f.text_field :name, placeholder: 'グループ名を入力してください', cols: '30', rows: '10', autofocus: 'true', class: 'form-control'
= f.text_area :description, placehoder: 'グループの説明を入力してください', autofocus: 'true', class: 'form-control'
= f.file_field :logo
= f.fields_for :members do |m|
= m.text_field :nickname
= m.file_field :avatar
= f.submit '作成する', class: 'btn btn-primary'
以下のようにコントローラーを記述することで、まとめて2つのテーブルのレコードを追加出来ます。
app/controller/teams_controlelr.rb
class TeamsController < ApplicationController
def create
Team.create(team_params)
end
end
private
def team_params
params.require(:team).permit(:name, :description, :logo, members_attributes: [:nickname, :avator])
end
参考
Railsでaccepts_nested_attributes_forとfields_forを使ってhas_many関連の子レコードを作成/更新するフォームを作成