Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

一つのフォームから複数の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テスト"}
ftyabu
CEO at Elaly, inc.
https://air-room.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away