Строки без имени или адреса электронной почты импортируются в базу данных из CSV-импорта - PullRequest
0 голосов
/ 03 мая 2018

Я пытаюсь загрузить данные из CSV в мое приложение Modular 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

база

database image

Проблема сейчас в том, что строки без имени и адреса электронной почты также импортируются в мою базу данных, что мне не нужно. Я использовал обратные вызовы - before_save на модели, но я думаю, что это не надежное решение для фильтрации строк без имени и адреса электронной почты от сохранения в моей базе данных.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Вы можете добавить проверку присутствия в вашей модели, синтаксис очень похож на проверку уникальности:

module CsvImporter
  class User < ApplicationRecord
    validates :name, :email_address, presence: true
    validates :email_address, uniqueness: true
  end
end

В вашем скрипте импорта вы также можете декларативно пропустить все строки, которые не соответствуют вашим критериям проверки:

CSV.foreach(filename, headers: true, header_converters: :symbol) do |row|
  # Jump to the next row in the CSV because this one is no good.
  next unless row[:name].present? && row[:email_address].present?

  user = CsvImporter::User.create row.to_h
  # . . .
end

Я должен также упомянуть, что если важно, чтобы :name и :email_address всегда присутствовали и никогда не были нулевыми (что, вероятно, верно), вы можете / должны добавить ограничение базы данных, чтобы убедиться, что вы действительно никогда не сможете создать User без этих полей. Существуют некоторые методы взаимодействия с объектами ActiveRecord , которые пропускают проверки , и поэтому вы можете удивиться, если используете один из них по незнанию и создаете плохие записи.

Миграция будет выглядеть примерно так:

class AddNotNullConstraintsToUsers < ActiveRecord::Migration
  def change
    change_column_null :users, :name, false
    change_column_null :users, :email_address, false
  end
end
0 голосов
/ 03 мая 2018

Для достижения этих проверок измените определение пользователя:

module CsvImporter
  class User < ApplicationRecord
    validates :email_address, uniqueness: true, presence: true
    validates :name, presence: true
  end
end

В этом случае duplicate_counter следует переименовать, например, unimported_counter.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...