2014-02-20 32 views
5

說我有下面的類:使用Ruby CSV標題轉換器

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

,並在CSV文件中的以下內容:

First Name,Last Name 
John,Doe 
Jane,Doe 

我想了CSV的內容保存到數據庫中。我曾經在一個耙文件中的以下內容:

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的正確語法是什麼?

+1

完全給出錯誤* undefined method'downcase'*,這有助於我們瞭解該方法被調用的對象。 –

+0

@ArupRakshit編輯了這個問題,它在'nil:NilClass'上。 – jcm

+0

只需在其中添加一個條目':return_headers => true'。我沒有測試,但希望它能起作用。如果有幫助,請告訴我,我會向你解釋發生的一切。 –

回答

15

在我的桌面上做了​​一些研究之後,在我看來,錯誤是爲了別的。

首先,我把數據放到我"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] 
#<CSV::Row "first_name":"John" "last_name":"Doe"> 
#<CSV::Row "first_name":"Jane" "last_name":"Doe"> 

所以一切都是工作了。現在讓我來重現錯誤:

我把數據放到我"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 <main>': 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 
+0

你是對的,在某處有一個額外的逗號,但奇怪的是,代碼仍然需要你最初的建議':return_headers => true'來工作。否則,它會給出一個「未定義的屬性:」錯誤。 – jcm

+0

@jcm然後添加,但沒有':return_headers => true',代碼在我這裏按預期運行。 –

7

一個更普遍的答案,但如果你有,你需要處理的文字,有時你可能會在那裏得到一個零代碼,然後在對象上調用to_s。這將變成空字符串爲零。例如

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

這不會炸燬,無論h是,因爲在Ruby每個類都有的to_s方法,它總是返回一個字符串(除非你重寫它做別的事情,這將是不明智的)。