activerecord-import gemを使用した再帰的インポート: 関連付けによる has_many が機能しない
概要
「activerecord-import gem」を使用してCSVファイルをデータベースにインポートしようとしています。 私は次のモデルを持っています
require 'csv'
class Question < ApplicationRecord
has_many :question_answers, dependent: :destroy
has_many :answers, through: :question_answers
belongs_to :category
belongs_to :product
class Answer < ApplicationRecord
has_many :question_answers, dependent: :destroy
has_many :questions, through: :question_answers
end
class QuestionAnswer < ApplicationRecord
belongs_to :question
belongs_to :answer
end
以下の方法は、CSV データを処理し、ActiveRecord import gem を使用して保存できるように準備することです。
def self.from_csv(file)
questions = []
CSV.foreach(file.path, headers: true) do |row|
category = Category.find_by(name: row['category'].strip)
product = Product.find_by(title: row['product'].strip)
parent_q = Question.find_by(qname: row['parent'])
question = Question.new(
question: row['question'],
qtype: row['qtype'],
tooltip: row['tooltip'],
parent: parent_q,
position: row['position'],
qname: row['qname'],
category_id: category.id,
product_id: product.id,
state_id: row['state_id'],
explanation: row['explanation']
)
answers = row['answers'].split(" | ") if row['answers'].present?
if answers.present?
answers.each do |a_str|
answer_arr = a_str.split(',')
question.answers.build(answer: answer_arr[0] || "", value: answer_arr[1] || "", pdf_parag: answer_arr[2] || "", key: answer_arr[3] || "", position: answer_arr[4] || "", note: answer_arr[5] || "")
end
end
p question.answers.inspect
questions << question
end
imported_obj = Question.import questions, recursive: true, validate: false
end
コードは質問を挿入しますが、その答えがないと、次のようなエラーが表示されます。
NoMethodError (undefined method `answer_id=' for #<Answer:0x000000000>
Heroku を使用しています
CSVサンプル
助けていただければ幸いです
解決策
CSV がどのようなものであるかが分からないと、これ以上解決するのは難しいかもしれませんが、エラーはおそらく次の行からのものです。
question.answers.build(answer: answer_arr[0], ...)
その行の後半の属性はおそらく問題ありません (value、pdf_parag、key、position、note がすべて回答テーブルの列であると仮定しています。そうでない場合は、さらに問題が発生する可能性があります。) しかし、そこから始めています。答え:answer_arr[0]。
アンサー レコードに回答 (またはanswer_id) 属性を設定しようとしていると考えられます。 Answer_arr[0] がインポートするデータの ID であると仮定すると、answer:answer_arr[0] を ID:answer_arr[0] に置き換えてみることができます。
ただし、データをインポートしている場合は、インポートから ID を除外し、Rails に新しい ID を設定させることを検討することもできます。一般に、フレームワークによる主キーの管理方法をオーバーライドしようとするのは得策ではありません。質問に基づいて作成した回答を保存すると、Rails が賢く外部キーを正しく設定します。インポートするデータの ID をどうしても保持する必要がある場合は、ID を新しい列に入れることを検討してください。
それが正しくない場合は、エラー トレースと CSV からのサンプル データを提供してください。