【问题标题】:Unknown attribute error on CSV uploadCSV 上传时出现未知属性错误
【发布时间】:2018-01-16 18:51:36
【问题描述】:

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

错误:ActiveRecord::RecordInvalid 在 UploadsController#import 中!验证失败:电子邮件已被占用。

控制器

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 列)。有什么想法吗?

【问题讨论】:

  • 您可以添加迁移以将新属性last_name 添加到员工表中。
  • 还要仔细检查您正在运行上传的数据库是否与您手动检查列的数据库相同......即,如果您最近将该列添加到开发中并且它不在尚未生产,等等。
  • 感谢@MuhamadAkbarBinWidayat。见下文。我有last_name 作为我表中的一列。除非我错过了什么不知道该怎么做。
  • @jarlyon 您是否对您的Employee 模型上的email 进行了唯一性验证?它没有出现在您的帖子中,但错误是由于尝试在唯一列上插入重复值引起的。
  • 感谢@DRSE。那行得通!但我真的不明白为什么我有一个空数据库。那里的电子邮件不应该是唯一的吗?

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


【解决方案1】:

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

  • 有一列的标题不是全部小写。例如,CSV 列名称可以是“Email”或“EMAIL”,但应该是“email”。
  • 有一列的标题中有空格。例如,CSV 列名称可以是“first name”或“last name”,但应分别为“first_name”或“last_name”。
  • CSV 中有一个列,其中列标题拼写错误,或者根本不属于数据库中的表架构。 (虽然您说您的所有 CSV 列标题都与数据库表列匹配,但如果前两个项目符号没有解决问题,请再次检查。)

其中任何一个都会导致您看到的ActiveModel::UnknownAttributeError。如果问题是由上述一种或多种原因引起的,那么您显然可以通过编辑 CSV 文件以确保每个标题都是带有下划线而不是空格的小写字母来解决问题。或者,您可以将:header_converters =&gt; :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 模型上没有这样的属性)。正如 Muhamad 建议的那样,您可以创建迁移以将 last_name 列添加到 Employee。你能验证你数据库中的employees表有这个列吗?

【讨论】:

  • 感谢@drse。我试过了,谢谢——我添加了:header_converters =&gt; :symbol 现在得到一个不同的错误。有关新错误和表格,请参阅我的初始帖子
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2020-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
相关资源
最近更新 更多