说我有以下课程:
class Buyer < ActiveRecord::Base
attr_accesible :first_name, :last_name
Run Code Online (Sandbox Code Playgroud)
以及CSV文件中的以下内容:
First Name,Last Name
John,Doe
Jane,Doe
Run Code Online (Sandbox Code Playgroud)
我想将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
Run Code Online (Sandbox Code Playgroud)
结束
我得到了一个undefined method 'downcase' for nil:NilClass.如果我排除标题转换器,那么我得到unknown attribute 'First Name'.什么是对,比如说,从转换头的正确语法First Name来first_name?
Aru*_*hit 19
在我的桌面上做了一些研究后,在我看来错误是其他的东西.
首先,我将数据放在我的"a.txt"文件中,如下所示:
First Name,Last Name
John,Doe
Jane,Doe
Run Code Online (Sandbox Code Playgroud)
现在我运行了代码,该代码保存在我的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
Run Code Online (Sandbox Code Playgroud)
现在运行:
C:\Users\arup>ruby -v so.rb
ruby 1.9.3p448 (2013-06-27) [i386-mingw32]
#<CSV::Row "first_name":"John" "last_name":"Doe">
#<CSV::Row "first_name":"Jane" "last_name":"Doe">
Run Code Online (Sandbox Code Playgroud)
所以现在一切正常.现在让我重现错误:
我把数据放在我的"a.txt"文件中如下(只是,在最后一列之后添加了一个):
First Name,Last Name,
John,Doe
Jane,Doe
Run Code Online (Sandbox Code Playgroud)
现在我so.rb再次运行保存在我的文件中的代码.
C:\Users\arup>ruby -v so.rb
ruby 1.9.3p448 (2013-06-27) [i386-mingw32]
so.rb:5:in `block in <main>': undefined method `downcase' for nil:NilClass (NoMethodError)
Run Code Online (Sandbox Code Playgroud)
看来,在标题行中,存在导致错误的空白列值.因此,如果您对源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
Run Code Online (Sandbox Code Playgroud)
一个更一般的答案,但如果你有需要作为文本处理的代码,有时你可能会在那里得到一个nil,那么在对象上调用to_s.这将把nil变为空字符串.例如
h.to_s.downcase.gsub(' ', '_')
Run Code Online (Sandbox Code Playgroud)
无论h是什么,这都不会爆炸,因为ruby中的每个类都有to_s方法,并且它总是返回一个字符串(除非你重写它以做其他事情,这是不可取的).