Ruby on rails 没有名称或电子邮件地址的行从CSV导入导入到数据库中

Ruby on rails 没有名称或电子邮件地址的行从CSV导入导入到数据库中,ruby-on-rails,ruby,Ruby On Rails,Ruby,我试图将CSV中的数据上传到我的模块化Rails应用程序中,所以我创建了一个rake文件来轻松实现这一点。代码如下: import.rake require 'csv' namespace :import do desc 'Import users from csv' task users: :environment do # filename = File.join Rails.root, '/engines/csv_importer/people.csv' fil

我试图将CSV中的数据上传到我的模块化Rails应用程序中,所以我创建了一个rake文件来轻松实现这一点。代码如下:

import.rake

require 'csv'

namespace :import do
  desc 'Import users from csv'

  task users: :environment do
    # filename = File.join Rails.root, '/engines/csv_importer/people.csv'
    filename = File.join Rails.root, 'engines', 'csv_importer', 'people.csv'
    counter = 0
    duplicate_counter = 0

    user = []
    CSV.foreach(filename, headers: true, header_converters: :symbol) do |row|
      user = CsvImporter::User.create row.to_h
      if user.persisted?
        counter += 1
      else
        duplicate_counter += 1
      end
    end
    p "Duplicate record: #{user.email_address} - #{user.errors.full_messages.join(',')}" if user.errors.any?

    p "Imported #{counter} users, #{duplicate_counter} duplicate rows ain't added"
  end
end
user.rb

module CsvImporter
  class User < ApplicationRecord
    validates :email_address, uniqueness: true
  end
end
模块CsvImporter
类用户<应用程序记录
验证:电子邮件地址,唯一性:true
结束
结束
数据库

require 'csv'

namespace :import do
  desc 'Import users from csv'

  task users: :environment do
    # filename = File.join Rails.root, '/engines/csv_importer/people.csv'
    filename = File.join Rails.root, 'engines', 'csv_importer', 'people.csv'
    counter = 0
    duplicate_counter = 0

    user = []
    CSV.foreach(filename, headers: true, header_converters: :symbol) do |row|
      user = CsvImporter::User.create row.to_h
      if user.persisted?
        counter += 1
      else
        duplicate_counter += 1
      end
    end
    p "Duplicate record: #{user.email_address} - #{user.errors.full_messages.join(',')}" if user.errors.any?

    p "Imported #{counter} users, #{duplicate_counter} duplicate rows ain't added"
  end
end

我现在遇到的问题是,没有名字和电子邮件地址的行也被导入到我的数据库中,这是我不想要的。在保存之前,我在模型上使用了回调-
,但我认为这不是一个健壮的解决方案,无法将没有姓名和电子邮件地址的行过滤到我的数据库中


谢谢。

要实现这些验证,请更改您的用户定义:

module CsvImporter
  class User < ApplicationRecord
    validates :email_address, uniqueness: true, presence: true
    validates :name, presence: true
  end
end
模块CsvImporter
类用户<应用程序记录
验证:电子邮件地址,唯一性:true,存在性:true
验证:名称,状态:true
结束
结束

在这种情况下,
duplicate\u counter
应该重命名,例如,
unported\u counter

您可以在模型中添加状态验证,语法与唯一性验证非常相似:

module CsvImporter
  class User < ApplicationRecord
    validates :name, :email_address, presence: true
    validates :email_address, uniqueness: true
  end
end
我还应该提到,如果
:name
:email\u address
始终存在且从不为null(这可能是真的)这一点很重要,那么您可以/应该添加一个数据库约束,以确保在没有这些字段的情况下确实无法创建
用户。有一些与ActiveRecord对象交互的方法,因此,如果您在不知情的情况下使用其中一种方法并创建坏记录,您会感到惊讶

迁移过程如下所示:

class AddNotNullConstraintsToUsers < ActiveRecord::Migration
  def change
    change_column_null :users, :name, false
    change_column_null :users, :email_address, false
  end
end
类AddNotNullConstraintsToUsers
您可能会发现特别有用(向下滚动到显示“状态”的位置)。是的,但我需要更多的ruby方法来处理它,而不是回调。不管怎样,我已经得到了一个提示,并将其标记为有用。