Rails CSV导入,添加到相关表

时间:2010-05-13 13:39:37

标签: ruby-on-rails csv

我的应用程序上有一个csv导入系统(仅在本地使用),它逐行解析csv文件并将数据添加到数据库表中。这是基于教程here

require 'csv'

def csv_import 
  @parsed_file=CSV::Reader.parse(params[:dump][:file])
  n = 0
  @parsed_file.each_with_index  do |row, i|
    next if i == 0  #ignore the first row
    course = Course.new
    course.title = row[0]
    course.unit_code = row[1]
    course.course_type = row[2]
    course.value = row[3]
    course.pass_mark = row[4]
    if course.save
      n = n+1
      GC.start if n%50==0
    end
    flash.now[:message] = "CSV Import Successful, #{n} new courses added to the database."
  end
  redirect_to(courses_url) 
end

这一切都在课程控制器中,并且工作正常。 HABTM多年和多年的HABTM课程是一种关系。在csv文件中(有效地在行[5]到行[8]中)是year_id s。有没有办法可以在上面的方法中添加它。我很困惑如何循环这4个项目并将它们添加到courses_years表。

谢谢 千斤顶

2 个答案:

答案 0 :(得分:2)

您可以在将“普通”数据添加到模型后使用<<<<<<追加年度协会的方法。

...
course.value = row[3]
course.pass_mark = row[4]
5.upto(8).each do |i|
  one_year = Year.find(row[i])
  course.years << one_year if one_year
end
if course.save
  n = n+1
...

如果要确保值有效,可以在循环中添加更多检查,和/或更改查找以另一种方式查找年份。另一种方式,当相关数据像这样“拖尾”时,继续添加,直到没有任何东西可以添加,并且如果它们还不存在,还要自己添加年份:

...
course.value = row[3]
course.pass_mark = row[4]
row[5..-1].each do |year_id|
  one_year = Year.find_or_create_by_id(year_id)
  course.years << one_year
end
if course.save
  n = n+1
...

有很多不同的方法可以做到这一点,而正确的方式实际上取决于您的实际数据,但这是基本方法。

答案 1 :(得分:1)

在保存课程之前,您是否尝试过其中任何一项:

course.years.push(row[5])
course.years.push(row[6])
course.years.push(row[7])
course.years.push(row[8])

OR

course.years = [ row[5], row[6], row[7], row[8] ]

在保存课程之前放置它。它将填补联合表课程_年。

修改

你得到的错误似乎是因为我们试图放入id而不是对象,我们应该这样做:

  .....
  year_array = Year.find(row[5], row[6], row[7], row[8])
  course.years << year_array
  .....

获得年份对象后,我们将其放入关联中。之后您可以保存课程对象。