2010-05-13 66 views
3

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

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。有没有一种方法可以在上面的方法中添加。我很困惑如何循环4个项目并将它们添加到courses_years表中。

谢谢 杰克

回答

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

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

+0

非常好。非常感谢。你有什么想法在哪里我可以找到更多关于<<方法?这是很难找到使用谷歌... – Jack 2010-05-13 14:16:21

+1

apidock.com是一个伟大的网站查找铁轨相关文件。您正在寻找我认为的ActiveRecord关联方法:http://apidock.com/rails/ActiveRecord/Associations/ClassMethods – jamuraa 2010-05-13 14:22:24

+0

宾果。伟大的网站。最后一件事。当我使用第二个例子时,服务器似乎陷入循环。我错过了什么吗? – Jack 2010-05-13 14:24:36

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

将它保存课程之前。它将填补联合表courses_years。

编辑

,你得到好像是因为我们正试图把ID的,而不是对象的错误,我们应该这样做,而不是:

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

后,我们得到了一年的对象,然后我们把它放在协会里面。之后您可以保存课程对象。

+0

感谢您的回复。我不断收到以下错误: 年(#2183546760)预计,得到CSV ::单元(#2156593920) 有什么建议吗? – Jack 2010-05-13 14:08:16

+1

查看我编辑的答案,我假设年模型数据可用,如果没有,我们将以不同的方式做。 – 2010-05-13 14:27:05

+0

非常好,欢呼声。有没有简单的方法来循环数组的创建,所以如果一个单元格是空的,它会跳过它? jamuraa已经在他的代码中尝试了这个,但它似乎没有工作。有任何想法吗? – Jack 2010-05-13 15:05:01