CSV上传时出现未知属性错误

时间:2017-08-09 03:29:28

标签: ruby-on-rails database csv model-view-controller upload

我正在尝试将CS​​V文件上传到现有数据库并接收以下内容

  

错误:UploadsController#import中的ActiveRecord :: RecordInvalid!验证失败:已经收到电子邮件。

控制器

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 个答案:

答案 0 :(得分:0)

您提供给Employee.create!的哈希键(本例中为CSV标题)需要与模型上的属性名称完全匹配。您的问题可能是由以下一项或多项引起的:

  • 列中的标题不是全部小写。例如,CSV列名称可以是&#34;电子邮件&#34;或者&#34; EMAIL&#34;但应该是&#34;电子邮件&#34;。
  • 标题中有一个空格。例如,CSV列名称可以是&#34;名字&#34;或者&#34;姓氏&#34;但应该是&#34; first_name&#34;或者&#34; last_name&#34;,分别。
  • 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

此选项将通过将标题转换为小写,用下划线替换空格,然后将它们转换为符号来转换标题。如果你有很多列标题需要整理,或者如果你经常会收到文件,那么这可能是一个更可靠的选择。&#34;稍差&#34;遭遇上述问题之一的标题。

修改

我看到您更新了有关错误的详细信息。 Rails告诉你有一个带标题的列&#34; last_name&#34;在您的CSV中,但数据库中没有此类列(即Employee模型上没有此类属性)。正如Muhamad建议的那样,您可以创建迁移以将last_name列添加到Employee。您能否验证数据库中的employees表是否包含此列?