Madogiwa Blog

主に技術系の学習メモに使っていきます。

RubyonRails:accepts_nested_attributes_forとfields_forを使って紐づくモデルのフォームを作成する

railsの機能のaccepts_nested_attributes_forfields_forを使うと紐づくモデルも合わせて簡単に作成できたのでメモφ(..)メモメモ

今回の想定ケース

今回はクイズのように質問があって、それに紐づく選択肢があるようなケースを想定してます。
実装イメージはこんな感じです🙌 f:id:madogiwa0124:20180603212606p:plain

手順

手順はこんな感じです。

  • Modelに合わせて作成するモデルをaccepts_nested_attributes_forで設定
  • Controllerで合わせて作成するモデルのインスタンスを生成
  • Viewでfields_forを使って合わせて作成するモデルのフォームを作成

Model

class Quiz < ApplicationRecord
  has_many :choices, dependent: :destroy
  # 合わせて作成するモデルを`accepts_nested_attributes_for`で設定
  accepts_nested_attributes_for :choices
end

class Choice < ApplicationRecord
  belongs_to :quiz
end

Controller

class QuizzesController < ApplicationController
  def new
    @quiz = Quiz.new
    # 合わせて作成するモデルのインスタンスを生成
    @quiz.choices.new
    # 複数のフォームを作る場合は、複数回newする
    # n.times { @quiz.choices.new }
  end

  def create
    @quiz = Quiz.new(quiz_params)
    if @quiz.save
      redirect_to quizzes_path
    else
      render :new
    end
  end

  private

  def quiz_params
    params.require(:quiz).permit(:title, :body, :explanation, choices_attributes: %i[id sentence correct])
  end
end

View

= form_for @quiz do |f|
  - if @quiz.errors.any?
    = render 'layouts/error_form', resource: @quiz
  .form-group
    = f.label :title, 'タイトル'
    %br
    = f.text_field :title
  .form-group  
    = f.label :body, '本文'
    %br
    = f.text_area :body  
  .form-group
    = f.label :explanation, '解説'
    %br
    = f.text_area :explanation
  .form-group.choices_area
    %h3 選択肢
    %ul
      - # `fields_for`を使って合わせて作成するモデルのフォームを作成
      = f.fields_for :choices do |choice|
        %li
          = choice.text_field :sentence
          = choice.check_box :correct
  = f.submit '保存'

参考資料

fields_for - リファレンス - - Railsドキュメント

api.rubyonrails.org

ruby-rails.hatenadiary.com