2017-08-09 57 views
0

我想上傳一個CSV文件導入到現有的數據庫,並接受下列未知屬性錯誤上傳

error: ActiveRecord::RecordInvalid in UploadsController#import! Validation failed: Email has already been taken.

控制器

class UploadsController < ApplicationController 
    def index 
    @uploads = Upload.all 
    end 

    def import 
    Upload.import(params[:file]) 
    redirect_to uploads_path, notice: "Employee data imported!" 
    end 
end 

型號

class Upload < ActiveRecord::Base 
    require 'csv' 

    def self.import(file) 
    CSV.foreach(file.path, headers: true) do |row| 
     Employee.create! row.to_hash 
    end 
    end 
end 

create_table "employees", force: :cascade do |t| 
    t.string "last_name" 
    t.string "first_name" 
    t.string "employee_code" 
    t.string "email" 
    t.string "level" 
    t.string "dept" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
end 

我檢查,併爲員工我的數據庫頭不符合我的CSV文件(開始第1行,第1欄)的第一行。有什麼想法嗎?

+1

您可以添加遷移以將新屬性'last_name'添加到employees表中。 – akbarbin

+0

同時仔細檢查您正在運行上載的數據庫是否是您手動檢查列的相同數據庫....即,如果您最近將該列添加到了開發中,並且它尚未投入生產,等等。 –

+0

感謝@MuhamadAkbarBinWidayat。見下文。我把'last_name'作爲我的表中的一列。除非我錯過了一些不知道該怎麼做的事情。 – jarlyon

回答

0

您提供給Employee.create!(本例中爲CSV標頭)的哈希鍵需要與模型上屬性的名稱完全匹配。您的問題可能是由以下一項或多項原因造成的:

  • 有一列的標題並非全部爲小寫。例如,CSV列名可以是「電子郵件」或「電子郵件」,但應該是「電子郵件」。
  • 有一個標題中有空格的列。例如,CSV列名可以是「名」或「姓」,但應分別是「first_name」或「last_name」。
  • 在CSV中存在一列,其中列標題拼寫錯誤,或者根本不屬於數據庫中的表模式。 (雖然你說你所有的CSV欄標題匹配的數據庫表列,也許再次檢查,如果問題不是由前兩個子彈解決。)

上述任何一個會引起你所看到的ActiveModel::UnknownAttributeError 。如果問題是由上述一個或多個問題引起的,那麼您可以通過編輯CSV文件來明確解決問題,以確保每個標頭都帶有下劃線而不是空格。或者,你可以在:header_converters => :symbol選項傳遞給CSV.foreach這樣的:

CSV.foreach(file.path, headers: true, header_converters: :symbol) do |row| 
    Employee.create! row.to_hash 
end 

此選項將它們轉換爲小寫,用下劃線代替空格,然後將它們轉換爲符號改變你的頭。如果您需要清理很多列標題,或者如果您經常收到帶有「稍差」標題的文件,並且遇到上述問題之一,那麼這可能是更可靠的選項。

編輯

我看到了有關該錯誤的更多詳細更新你的問題。 Rails告訴你,CSV中有一個標題爲「last_name」的列,但數據庫中沒有這樣的列(即Employee模型中沒有這樣的屬性)。正如穆罕默德所建議的那樣,您可以創建一個遷移來將last_name列添加到Employee。你能否驗證你的僱員表在數據庫中有這個專欄?

+0

謝謝@drse。我試過謝謝 - 我添加了':header_converters =>:symbol'現在得到了一個不同的錯誤。看到我的初始職位,爲新的錯誤和表 – jarlyon