質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1223閲覧

Seed_fuで中間テーブルの登録を再現したい。

sansan001

総合スコア2

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/06/07 07:54

編集2021/06/07 21:11

前提・実現したいこと

初学者エンジニアです。
現在Railsを使用しアンケート機能を作成中で、質問内容をタグで管理したいと考えています。
質問内容とタグは多対多の関係性で作成しようと考えています。
seed_fuというgemを使用し、データを登録させようと考えているのですが中間テーブルの登録がうまく実装できず、この度質問させていただきました。

質問内容を管理するモデル

class QuestionnaireForm < ApplicationRecord has_and_belongs_to_many :questionnaire_tags validates :title, presence: true end

質問管理用のタグのテーブル

class QuestionnaireTag < ApplicationRecord has_and_belongs_to_many :quetionnaire_forms validates :title, presence: true end

中間テーブル

class QuestionnaireFormTag < ApplicationRecord belongs_to :questionnaire_tag belongs_to :questionnaire_form end
create_table "questionnaire_form_tags", force: :cascade do |t| t.bigint "questionnaire_tag_id", null: false t.bigint "questionnaire_form_id", null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false end create_table "questionnaire_forms", force: :cascade do |t| t.bigint "questionnaire_id", null: false t.string "title", null: false t.integer "display_order", null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false end create_table "questionnaire_tags", force: :cascade do |t| t.string "title", null: false t.integer "display_order", null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false end

questionnaire_form.rb(seed作成している部分)

require 'csv' CSV.table("#{Rails.root}/db/fixtures/csv/questionnaire_form.csv").each do |record| next if record[:id].nil? questionnaire = QuestionnaireForm.seed do |s| s.id = record[:id] s.title = record[:title] s.display_order = record[:display_order] s.questionnaire_id = 1 end questionnaire_tag_ids =[] case record[:display_order] when (1..14) questionnaire_tag_ids = [QuestionnaireTag.find_by(display_order: 1), QuestionnaireTag.find_by(display_order: 2)] when (15..35) questionnaire_tag_ids = [QuestionnaireTag.find_by(display_order: 1), QuestionnaireTag.find_by(display_order: 3)] when (36..68) questionnaire_tag_ids = [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 6)] when 69 questionnaire_tag_ids = [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 4)] when 70 questionnaire_tag_ids = [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 5)] when (71..100) questionnaire_tag_ids = [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 8)] end questionnaire.questionnaire_tags << questionnaire_tag_ids end

CSVを使用していますがCSV内には質問内容等の具体的な情報が含まれています。
今回のエラーは上記テキスト最後の行の

questionnaire.questionnaire_tags << questionnaire_tag_ids

の部分でquestionnaire_tags が見つからずNoMethodErrorとなってしまいます。
エラーコードを確認し、byebugでデバッグもしましたが最後のタグデータを参照しようとする部分でエラーが発生しており原因がわからず苦戦しています。

発生している問題・エラーメッセージ

エラーメッセージ == Filtering seed files against regexp: /questionnaire_form.rb/ == Seed from /var/www/app/db/fixtures/questionnaire_form.rb - QuestionnaireForm {:id=>1, :title=>"朝食を食べますか?", :display_order=>1, :questionnaire_id=>1} rails aborted! NoMethodError: undefined method `questionnaire_tags' for #<Array:0x0000558675da1a00>

試したこと

https://mbleigh.lighthouseapp.com/projects/10223/tickets/7-ability-to-set-habtm-associations

上記サイトを参照し一度QuestionnaireFormを作成した後そこにquestionnaire_tag_idsを指定する方法をとりましたが変わらず上記エラーが発生してしまいます。

どんな些細な事でもご指摘頂けますと幸いです。
よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

seed_fuのseedメソッドは仕様変更したようでモデルインスタンスの配列を返します。
なので、ブロックを渡して一つだけ作成する場合は

ruby

1questionnaire,* = QuestionnaireForm.seed do |s|

等と、最初の要素だけを配列に入れるなりしないといけません。


参考までにもうちょい新しいissueでのコメントを見た感じ

ruby

1def tag_ids(display_order) 2 case display_order 3 when (1..14) 4 [QuestionnaireTag.find_by(display_order: 1), QuestionnaireTag.find_by(display_order: 2)] 5 when (15..35) 6 [QuestionnaireTag.find_by(display_order: 1), QuestionnaireTag.find_by(display_order: 3)] 7 when (36..68) 8 [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 6)] 9 when 69 10 [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 4)] 11 when 70 12 [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 5)] 13 when (71..100) 14 [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 8)] 15 end 16end 17 18CSV.table("#{Rails.root}/db/fixtures/csv/questionnaire_form.csv").each do |record| 19 next if record[:id].nil? 20 QuestionnaireForm.seed do |s| 21 s.id = record[:id] 22 s.title = record[:title] 23 s.display_order = record[:display_order] 24 s.questionnaire_id = 1 25 s.questionnaire_tags << tag_ids(record[:display_order]) 26 end 27 tags = tag_ids(record[:display_order]) 28 tags.each do |t| 29 QuestionnaireFormsTag.seed do |s| 30 s.questionnaire_tag = t 31 s.questionnaire_form = QuestionnaireForm.find(record[:id]) 32 end 33 end 34end

みたいに分けるようですね

投稿2021/06/08 00:38

編集2021/06/08 01:35
asm

総合スコア15149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sansan001

2021/06/08 22:39

ありがとうございます! 少し修正したところエラーなく実装する事ができました! ベストアンサーとさせていただきます! ``` require 'csv' def tag_ids(display_order) case display_order when (1..14) [QuestionnaireTag.find_by(display_order: 1), QuestionnaireTag.find_by(display_order: 2)] when (15..35) [QuestionnaireTag.find_by(display_order: 1), QuestionnaireTag.find_by(display_order: 3)] when (36..68) [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 6)] when 69 [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 4)] when 70 [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 5)] when (71..100) [QuestionnaireTag.find_by(display_order: 9), QuestionnaireTag.find_by(display_order: 8)] end end CSV.table("#{Rails.root}/db/fixtures/csv/questionnaire_form.csv").each do |record| next if record[:id].nil? QuestionnaireForm.seed do |s| s.id = record[:id] s.title = record[:title] s.display_order = record[:display_order] s.questionnaire_id = 1 s.questionnaire_tags = tag_ids(record[:display_order]) end tags = tag_ids(record[:display_order]) tags.each do |t| QuestionnaireFormsTag.seed do |s| s.questionnaire_tag = t s.questionnaire_form = QuestionnaireForm.find(record[:id]) end end end ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問