是否有rails方法来遍历上传文件的每一行? “each_line”是一种IO方法,但它不起作用

我正在尝试上传一个csv文件,解析它,并为S3吐出一个文件或者只是传递给查看。 我使用file_field_tag上传csv。 我认为file_field_tag传递一个对象,该对象是IO的子类,并且将具有所有ruby IO方法,例如“each_line”。 我可以在对象(IO类的方法)上调用“read”而不是“each_line”…所以如何迭代file_field_tag上传的每一行?

创建我的控制器的方法:

@csv_file = params[:csv_file] 

我的show view会抛出一个没有“each_line”方法的错误:

    

但我可以使用

  

我真的很困惑file_field_tag上传params []有哪些方法… each_line,得到不起作用……我似乎无法找到我可以使用的列表。

编辑我通过这样做来解决这个问题:

 @csv_file = params[:csv_file].read.to_s 

然后迭代:

    

编辑2正在上传的文件在不包含逗号的行后重复标题(不要问)…所以我找到没有逗号的行并调用.gets(在我的rb脚本中独立于rails)。 不幸的是我得到一个错误,关于获取我无法调用的私有方法。 这可以追溯到我最初的问题。 使用IO方法(例如read_lines&gets),文件不是IO的子类吗?

  @file_out = [] @file_in.each_line do |line| case line when /^[^,]+$/ @comp = line.to_s.strip comp_header = @file_in.gets.strip.split('') @file_out.push(@comp) end end 

当你发布’file_field’时,返回给控制器的param有一些特殊的魔法。

即在你的情况下,你可以这样做

 <%= "The following file was uploaded #{params[:csv_file].original_filename}" %> <%= "It's content type was #{params[:csv_file].content_type}" %> <%= "The content of the file is as follows: #{params[:csv_file].read}" %> 

所以这些是你可以在params [:csv_file]上调用的三种特殊方法,或者在视图中成功发送’file_field_tag’或’f.file_field’的任何params

请记住,这些是你可以通过file_field发布的一个参数的三个额外的特殊事物:

original_filename

内容类型

您已清楚地知道如何进行读取,原始文件名和content_type可能会在将来帮助您。

编辑

好的,所以你只需要读取方法,它将读取上传文件的内容。

 contents = params[:csv_file].read 

所以现在内容是一个包含文件内容的字符串,但除了它是csv文件之外,没有其他任何关于该文件的信息。 我们知道csvs用’\ r’分隔(我想,我在解析csv方面做了很多工作,但是我太懒了去检查)

所以你可以这样做:

 contents = params[:csv_file].read contents.split("\r").each do |csvline| ??? end 

编辑2

所以这是从这篇文章中删除

当您将file_field发布到控制器时,最常见的事情是将上传文件的内容“读取”为ruby String。 必须对从’read’返回的ruby字符串执行上载内容的任何其他处理。

在这种特殊情况下,如果上传的文件始终是CSV,您可以假定CSV并开始相应地解析它。 如果您期望多种上传格式,则必须处理该格式,例如:

 contents = params[:csv_file].read case params[:csv_file].content_type when 'txt/csv' contents.split("\r").each do |csvline| ??? end when 'application/pdf' ??? end