1つのフォームで複数のモデルを扱う [Ruby on Rails]
1つのフォームで複数のモデルを扱う方法です。
例として「掲示板システム」の機能である、新規質問の登録に焦点を当てます。新規質問の際には「questions」(質問テーブル)、「answers」(回答テーブル)に各1レコードが作成される仕様とします。
モデル(テーブル構成)
questions - 質問テーブル
項目名 | 型 | 備考 |
---|---|---|
id | integer | |
title | string | タイトル |
answers - 回答テーブル
項目名 | 型 | 備考 |
---|---|---|
id | integer | |
question_id | integer | questionsテーブルのid |
name | string | 名前 |
url | string | URL |
body | string | 本文 |
今回はテーブルを1:Nの親子関係にしていますが、全く無関係の複数モデルでもOKです。
コントローラー側
newは新規質問の登録画面。createでテーブルの登録処理を行います。question_params及びanswer_paramsはストロングパラメータで不正なパラメータを防ぎます。
def new @question = Question.new @answer = Answer.new end def create @question = Question.new(question_params) @answer = Answer.new(answer_params[:answer]) ・・・登録処理 ・・・ end private def question_params params.require(:question).permit(:title) end def answer_params params.require(:question).permit(answer:[:name, :url, :body]) end
ビュー側
SlimとBootstrap4を使用しています。※erbの方は後述するHTMLを参考。
= form_with model: @question, local: true do |f| .form-group = f.label :title = f.text_field :title, class: 'form-control', id: 'question_title' = f.fields_for @answer do |i| .form-group = i.label :name = i.text_field :name, class: 'form-control', id: 'question_answer_name' .form-group = i.label :url = i.text_field :url, class: 'form-control', id: 'question_answer_url' .form-group = i.label :body = i.text_area :body, rows: 5, class: 'form-control', id: 'question_answer_body' = f.submit '作成する', class: 'btn btn-primary'
form_withのモデルが親で、fields_forは子の扱いです。
このフォームがPOSTで送信するパラメータは次のような形式になります。
{ "utf8"=>"✓", "question"=> { "title"=>"質問のタイトル", "answer"=> { "name"=>"名前", "url"=>"https://www.petitmonte.com/", "body"=>"本文です。" } }, "commit"=>"作成する" }
HTML(ビューの出力例)
<form action="/questions" accept-charset="UTF-8" method="post"> <div class="form-group"> <label for="question_title">タイトル</label><input class="form-control" id="question_title" type="text" name="question[title]" /> </div> <div class="form-group"> <label for="question_answer_name">名前</label><input class="form-control" id="question_answer_name" type="text" name="question[answer][name]" /> </div> <div class="form-group"> <label for="question_answer_url">URL</label><input class="form-control" id="question_answer_url" type="text" name="question[answer][url]" /> </div> <div class="form-group"> <label for="question_answer_body">本文</label><textarea rows="5" class="form-control" id="question_answer_body" name="question[answer][body]"> </textarea> </div> <input type="submit" name="commit" value="作成する" class="btn btn-primary" data-disable-with="作成する" /> </form>
以上です。
スポンサーリンク
関連記事
前の記事: | タイトル/メタタグ(keywords,description)をページ毎に変更する [Ruby on Rails] |
次の記事: | ransackで親子関係テーブルの検索 [Ruby on Rails] |
公開日:2019年10月18日
記事NO:02794