尝试使用“ 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导入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样本
我们非常感谢您的帮助
答案 0 :(得分:0)
不知道您的csv是什么样子,可能很难提供更多帮助,但是错误可能出在线路上:
question.answers.build(answer: answer_arr[0], ...)
该行中的后一个属性可能没问题,(我假设value
,pdf_parag
,key
,position
和note
都是答案表上的所有列。如果不正确,则可能会有更多问题。),但您要以answer: answer_arr[0]
开始。
它认为您正在尝试在answer
记录上设置answer_id
(或answer
)属性。假设answer_arr[0]
是要导入的数据的ID,则可以尝试将answer: answer_arr[0]
替换为id: answer_arr[0]
。
但是,如果要导入数据,则可能要考虑将ID排除在导入之外,而让Rails为您设置新的ID。一般来说,尝试覆盖框架如何管理主键是一个坏主意。一旦保存了基于问题的答案,Rails就会很聪明并正确设置外键。如果您绝对需要保留要导入数据中的ID,请考虑将其放在新列中。
如果这不正确,请提供错误跟踪并提供csv中的一些示例数据。