139
162

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Rails】複数のレコードを作成する。modelの関係性によって異なるform_for / fields_forの使い方

Posted at

一つのフォームから複数のmodelにデータを送りたい場合に使用するのが、form_for / fields_forです。ただし、その複数存在するmodel間の関係性によって微妙に使い方が違うのをご存知ですか??今回は、その違いをまとめてみました。

親と子の要素を一度に作成したい場合

userとそのuserの書いたbook(つまり、user_idを持つbook)をまとめて作成したい場合
  • model
user.rb
has_many :books: 

accepts_nested_attributes_for :books: 
book.rb
belongs_to :user
  • controller
users_controller.rb
class UsersContoller < AppricationController
	def new
	@user = User.new
	@user.books.build
	# controllerのポイント
	# @user.books.build ←これで一括保存の準備は完了
	end
	
	def create
	user = User.new(user_params)
	user.save
	# 親要素を保存かけてあげることで自動で子要素も保存されます!
	end
	
	private 
	
		def user_params
			params.require(:user).permit(:name, books_attributes: [:title, published_at])
			# これは独特な書き方ですが、このように子要素のstrong parameterを書くことで、自動で子要素に親要素のidもふられます。この場合だと、bookテーブルにあるuser_idにもきちんとこの時作成される親要素のidがふられます。
		end
end
  • view
users/new.html.erb
<%= form_for :user do |f| %>
	<%= f.text_field :name %>
	
	<%= f.fields_for :books do |b| %>
		<%= b.text_field :title %>
		<%= b.text_field :published_at %>
	
	<%= f.submit %>
<% end %>

model間の関係は親子関係など特に無いが、一つのフォームから複数のmodelにむけてデータを送りたい場合

userテーブルとcorporationテーブルに一つのフォームからデータを送りたい場合
  • controller
users_controller.rb
class UsersController < ApplicationController
	def new
		@user = User.new
		@corporation = Corporation.new
		# それぞれ.newをする
	end
	
	def create
		user = User.new(user_params)
		user.save
		
		corporation = Corporation.new(corporation_params)
		corporation.save
		# それぞれcreate処理を行う
	end
	
	private
		
		def user_params
			params.require(:user).permit(:name)
		end
		
		def corporation_params
			params.require(:corporation).permit(:name)
		end
end
users/new.html.erb
<%= form_for @user, url: new_user_params do |f| %>
	<%= f.text_field :name %>
	
	<%= fields_for @corporation, new_corporation_params do |c| %>
		<%= c.text_field :name %>
		
	<%= f.submit %>
<% end %>

このようにして、model間の関係がないものも一つのフォームから送ることができます。
ちなみに、この場合パラメーターは以下のようになるので、それぞれstrog parameterでpermitしてあげてcreateすれば保存完了です。

{ "user" => { "name" => "userテスト"}, "corporation" => { "name" => "corporationテスト"}
139
162
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
139
162

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?