代码之家  ›  专栏  ›  技术社区  ›  Jack

Rails csv导入,添加到相关表

  •  4
  • Jack  · 技术社区  · 14 年前

    我的应用程序上有一个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]行中)是年份“s”。是否有方法可以将此添加到上述方法中?我对如何循环4个项目并将它们添加到课程年份表感到困惑。

    谢谢你 杰克

    2 回复  |  直到 14 年前
        1
  •  2
  •   jamuraa    14 年前

    您可以在将“普通”数据添加到模型后添加一个简单的循环,并使用<<方法将其附加到年份关联。

    ...
    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
    ...
    

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

        2
  •  1
  •   Samuel Chandra    14 年前

    在保存课程之前,您是否尝试过使用其中一种方法:

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

    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
      .....
    

    在我们得到年份对象之后,我们将它放入关联中。之后可以保存课程对象。