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
プチモンテ ※この記事を書いた人
![]() | |
![]() | 💻 ITスキル・経験 サーバー構築からWebアプリケーション開発。IoTをはじめとする電子工作、ロボット、人工知能やスマホ/OSアプリまで分野問わず経験。 画像処理/音声処理/アニメーション、3Dゲーム、会計ソフト、PDF作成/編集、逆アセンブラ、EXE/DLLファイルの書き換えなどのアプリを公開。詳しくは自己紹介へ |
| 🎵 音楽制作 BGMは楽器(音源)さえあれば、何でも制作可能。歌モノは主にロック、バラード、ポップスを制作。歌詞は抒情詩、抒情的な楽曲が多い。楽曲制作は🔰2023年12月中旬 ~ | |









