Ruby on rails Ruby CSV不读取带引号字符串中的逗号格式数字

Ruby on rails Ruby CSV不读取带引号字符串中的逗号格式数字,ruby-on-rails,ruby,csv,Ruby On Rails,Ruby,Csv,我在Rails应用程序中使用ruby的CSV类(ruby 2.1.5)从上传的CSV文件加载记录。用户使用“另存为”从Excel创建csv文件,根据数字的格式,这些文件可能会被保存为带引号的字符串,并带有逗号——在这种情况下,逗号后面的数字部分会被删除 如果输入值是“3500”,则应保存3500,但它是3 我意识到可以在Excel中清理这个问题,但它似乎也应该很容易处理(如果我不得不告诉用户程序无法处理这个基本情况,我会从用户那里得到一个主要的WTF。)此外,由于csv文件的标题与数据库中的列名

我在Rails应用程序中使用ruby的CSV类(ruby 2.1.5)从上传的CSV文件加载记录。用户使用“另存为”从Excel创建csv文件,根据数字的格式,这些文件可能会被保存为带引号的字符串,并带有逗号——在这种情况下,逗号后面的数字部分会被删除

如果输入值是
“3500”
,则应保存
3500
,但它是
3

我意识到可以在Excel中清理这个问题,但它似乎也应该很容易处理(如果我不得不告诉用户程序无法处理这个基本情况,我会从用户那里得到一个主要的WTF。)此外,由于csv文件的标题与数据库中的列名相匹配,我不必编写特定于列的处理程序——我只需进行属性赋值。我希望保持这种状态,因为我的受影响专栏比我在示例中包含的专栏多得多

输入记录:

recordid,valcurrent,valdate
11015,"3,500",6/7/2013
处理功能

def import_csv(file)
  CSV.foreach(file.path, headers: true, header_converters: :symbol, skip_blanks: true, converters: :all) do |row|
    # hash the input row 
    row_hash = row.to_hash
    # create a new row with the hash in original_record
    fl = self.forecast_lines.create(original_record: row_hash.to_s)
    # write the hash to the record attributes
    fl.attributes = row_hash
    fl.save
  end
end
原始记录哈希:

Original record: {:recordid=>"11015", :valcurrent=>"3,500", :valdate=>"6/7/2013"} 

valcurrent的数据类型为float。但是保存到数据库的当前值不是
3500.0
,而是
3.0

问题不在于CSV,而在于Ruby如何将字符串转换为float

在Ruby中:

"3,500".to_f => 3.0
这就是3.0被存储在数据库中的原因。您应该更改导入csv方法以处理逗号


另外,我认为您不应该在create中执行row\u hash.to\u。Create方法本身接受散列作为参数。

问题不在于CSV,而在于Ruby如何将字符串转换为float

在Ruby中:

"3,500".to_f => 3.0
这就是3.0被存储在数据库中的原因。您应该更改导入csv方法以处理逗号


另外,我认为您不应该在create中执行row\u hash.to\u。Create方法本身接受散列作为参数。

您可以添加一个正确处理数字列的自定义转换器。不确定这是否涵盖了所有可能的格式选项,但它看起来是这样的:

创建lambda:

comma_numbers = ->(s) {(s =~ /^\d+,/) ? (s.gsub(',','').to_f) : s}
将其添加到转换器:

CSV::Converters[:comma_numbers] = comma_numbers
新转换器未包含在converters::all中,因此请将其添加为数组:

converters: [:all, :comma_numbers]

您可以添加正确处理数字列的自定义转换器。不确定这是否涵盖了所有可能的格式选项,但它看起来是这样的:

创建lambda:

comma_numbers = ->(s) {(s =~ /^\d+,/) ? (s.gsub(',','').to_f) : s}
将其添加到转换器:

CSV::Converters[:comma_numbers] = comma_numbers
新转换器未包含在converters::all中,因此请将其添加为数组:

converters: [:all, :comma_numbers]

我了解您关于字符串到浮点转换的第一点,但我认为使用converters::all会导致CSV为我转换数字。关于你的第二点,我实际上想将整个散列保存为一个名为original_record的字段中的字符串,用于调试目的-在我的操作中没有解释。我了解你关于字符串到浮点转换的第一点,但我认为使用converters::all会导致CSV为我转换数字。关于你的第二点,我实际上想将整个散列作为字符串保存在名为original_record的字段中,用于调试目的-在我的操作中没有解释。谢谢-这非常有效,现在你已经为我指出了正确的方向,我将能够用它来处理其他情况。我根据我所做的工作对你的答案进行了编辑,但是如果有更好的方法,请更正。谢谢。我更新了上面的答案,明确指出您必须将新的转换器添加到转换器列表中。谢谢-这非常有效,现在您已经为我指出了正确的方向,我将能够使用它处理其他情况。我根据我所做的工作对您的答案进行了编辑,但是如果有更好的方法,请更正。谢谢。我更新了上面的答案,明确指出您必须将新转换器添加到转换器列表中。