使用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 Name
为first_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方法,并且它总是返回一个字符串(除非你重写它以做其他事情,这是不可取的)。