使用Ruby CSV标头转换器

说我有以下课程:

class Buyer < ActiveRecord::Base attr_accesible :first_name, :last_name 

以及CSV文件中的以下内容:

 First Name,Last Name John,Doe Jane,Doe 

我想将CSV的内容保存到数据库中。 我在Rake文件中有以下内容:

 namespace :migration do desc "Migrate CSV data" task :import, [:model, :file_path] => :environment do |t, args| require 'csv' model = args.model.constantize path = args.file_path CSV.foreach(path, :headers => true, :converters => :all, :header_converters => lambda { |h| h.downcase.gsub(' ', '_') } ) do |row| model.create!(row.to_hash) end end 

结束

我得到一个undefined method 'downcase' for nil:NilClass 。 如果我排除标题转换器,那么我将获得unknown attribute 'First Name' 。 将标题从First Namefirst_name的正确语法是什么?

在我的桌面上做了​​一些研究后,在我看来错误是其他的东西。

首先,我将数据放在我的"a.txt"文件中,如下所示:

 First Name,Last Name John,Doe Jane,Doe 

现在我运行了代码,该代码保存在我的so.rb文件中。

so.rb

 require 'csv' CSV.foreach("C:\\Users\\arup\\a.txt", :headers => true, :converters => :all, :header_converters => lambda { |h| h.downcase.gsub(' ', '_') } ) do |row| p row end 

现在运行:

 C:\Users\arup>ruby -v so.rb ruby 1.9.3p448 (2013-06-27) [i386-mingw32] # # 

所以现在一切正常。 现在让我重现错误:

我将数据放在我的"a.txt"文件中,如下所示(在最后一列之后添加了一个):

 First Name,Last Name, John,Doe Jane,Doe 

现在我再次运行代码,该代码保存在我的so.rb文件中。

 C:\Users\arup>ruby -v so.rb ruby 1.9.3p448 (2013-06-27) [i386-mingw32] so.rb:5:in `block in 
': undefined method `downcase' for nil:NilClass (NoMethodError)

看来,在标题行中,存在导致错误的空白列值 。 因此,如果您对源CSV文件具有控制权,请检查相同的内容。 或者对代码进行一些更改,以处理错误,如下所示:

 require 'csv' CSV.foreach("C:\\Users\\arup\\a.txt", :headers => true, :converters => :all, :header_converters => lambda { |h| h.downcase.gsub(' ', '_') unless h.nil? } ) do |row| p row end 

一个更一般的答案,但是如果你有需要作为文本处理的代码,有时你可能会在那里得到一个nil,那么在对象上调用to_s。 这将把nil变为空字符串。 例如

 h.to_s.downcase.gsub(' ', '_') 

无论h是什么,这都不会爆炸,因为ruby中的每个类都有to_s方法,并且它总是返回一个字符串(除非你重写它以做其他事情,这是不可取的)。