使用activerecord-import gem递归导入:has_many通过关联不起作用

时间:2019-07-19 15:36:37

标签: ruby-on-rails ruby activerecord-import

尝试使用“ activerecord-import gem”将CSV文件导入数据库。 我有以下型号

question.rb

require 'csv'
class Question < ApplicationRecord
    has_many :question_answers, dependent: :destroy
    has_many :answers, through: :question_answers
    belongs_to :category
    belongs_to :product

answer.rb

class Answer < ApplicationRecord
    has_many :question_answers, dependent: :destroy
    has_many :questions, through: :question_answers
 end

question_answer.rb

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

更新1

CSV样本

enter image description here

我们非常感谢您的帮助

1 个答案:

答案 0 :(得分:0)

不知道您的csv是什么样子,可能很难提供更多帮助,但是错误可能出在线路上:

question.answers.build(answer: answer_arr[0], ...)

该行中的后一个属性可能没问题,(我假设valuepdf_paragkeypositionnote都是答案表上的所有列。如果不正确,则可能会有更多问题。),但您要以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中的一些示例数据。