fields_for、check_box、enumで使用し、別モデルに複数レコードを作成する方法
実現したこと
- questionモデルのform内で別のモデルquestion_tagにレコードを保存する
- 1度のsubmitでquestion_id に対して複数のtagを付ける(複数レコード生成)
- enumで定義したタグをcheck_boxで表示する
・question_tags table こんな感じ
・Viewイメージ
(questionのレコードと同時にquestion_tagのレコードを複数生成する))
・questionsとquestion_tagsの関係
どうやったのか?
application.rb
localeを:ja(日本語)に設定する
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
config.i18n.default_locale = :jaを追加
require_relative 'boot' require 'rails/all' # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) module Stuttering class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 5.2 config.time_zone = 'Tokyo' config.active_record.default_timezone = :local config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] #I18nのload_pathにlacalesディレクトリ配下のrb,ymlを全て読む config.i18n.default_locale = :ja #localeを:ja(日本語)に設定する。 end end
locales/ja.yml
これでenumの英語を日本語と紐付けられる。
ja: enums: question_tag: tag: school: '学校' work: '仕事' job_hunting: '就活' relationship: '恋愛' improvement: '改善' hospital: '病院' other: 'その他'
question.rb
form_forの中で別のモデルに保存するためにaccepts_nested_attributes_for を記述します。
class Question < ApplicationRecord has_many :questionTags, dependent: :destroy accepts_nested_attributes_for :questionTags end
question_tag.rb
enumでtagを定義します。
class QuestionTag < ApplicationRecord belongs_to :question enum tag: { school: 0, work: 1, job_hunting: 2, relationship: 3, improvement: 4, hospital: 5, other: 10, } end
questions_controller.rb
@question.questionTags.buildを定義することでview内で f.fields_for のインスタンスを生成する。
保存するテーブル名_attributes: [:カラム]をストロングパラメータに追加することでform_forから別のモデルのパラメータを取得できる。
. . . def new @question = Question.new @question.questionTags.build end . . . private def question_params params.require(:question).permit(:title, :body, questionTags_attributes: [:tag]).merge(user_id: current_user.id) end end
new.html.haml
form_forの中にf.fields_forを定義することで、QuestionTagsテーブルにレコードを保存できる。
- QuestionTag.tags_i18n.map do |k, v|
= f.fields_for :questionTags do |qt|
= qt.label :tag, v
= qt.check_box(:tag,{:checked=>false}, k ,false)
QuestionTag.tags_i18nこちらで、enumで定義した英語と日本語の組み合わせがvalueとkeyのセットでハッシュとして取得できる。それぞれ、k、vのブロックに定義して、mapで繰り返すことで、enum分の数だけcheck_boxを生成し、更にチェックした分だけf.fields_forが繰り返されるので、チェック数だけレコードが保存される。
= form_for @question do |f| .form-group %h5.main-color-bottom-border タイトル =f.text_field :title, class: "form-control ",placeholder: "タイトル" .form-group.mt-2 %h5.main-color-bottom-border 質問のジャンルを選択 - QuestionTag.tags_i18n.map do |k, v| = f.fields_for :questionTags do |qt| = qt.label :tag, v = qt.check_box(:tag,{:checked=>false}, k ,false)
参考にさせていただきました。
【Rails 5.2】i18nでenumを日本語化 & モデル(model)別にYMLファイルを管理
Rails国際化 (I18n) API | Rails ガイド