ActiveRecord :: RecordInvalid: проверка не удалась: элемент должен существовать, при загрузке CSV - PullRequest
0 голосов
/ 29 ноября 2018

Когда я пытаюсь запустить мою задачу rake rake import:master

Я получаю эту ошибку: ActiveRecord::RecordInvalid: Validation failed: Item must exist

Когда я пытаюсь запустить отдельную задачу rake: rake import:item, явойдет в консоль rails и не будет отображать загруженные элементы.Кто-нибудь знает, что может быть не так?Я потратил часы, пытаясь понять это безрезультатно, любая помощь будет высоко ценится.

Вот мой файл граблей:

require 'csv'
namespace :import do 
  desc "Imports all CSV's"
  task :master => :environment do 
    Rake::Task["import:customer"].execute
    Rake::Task["import:merchant"].execute
    Rake::Task["import:item"].execute
    Rake::Task["import:invoice"].execute
    Rake::Task["import:transaction"].execute
    Rake::Task["import:invoice_item"].execute
  end 
end 

namespace :import do 
desc "imports merchants from a csv file"
task :merchant => :environment do 
    CSV.foreach("lib/seeds/merchants.csv") do |row|
    id = row[0]
    name = row[1]
    created_at = row[2]
    updated_at = row[3]
    Merchant.create(id: id, name: name, created_at: created_at, updated_at: updated_at)
    end 
  end 
end 

namespace :import do 
  desc "imports items from a csv file"
  task :item => :environment do 
      CSV.foreach("lib/seeds/items.csv") do |row|
      id = row[0]
      name = row[1]
      description = row[2]
      unit_price = row[3]
      merchant_id = row[4]
      created_at = row[5]
      updated_at = row[6]
      Item.create(id: id, name: name, unit_price: unit_price, merchant_id: merchant_id, created_at: created_at, updated_at: updated_at)
    end 
  end
end 

namespace :import do 
  desc "imports customers from a csv file"
  task :customer => :environment do
      CSV.foreach("lib/seeds/customers.csv") do |row|
      id = row[0]
      first_name = row[1]
      last_name = row[2]
      created_at = row[3]
      updated_at = row[4]
      Customer.create(id: id, first_name: first_name, last_name: last_name, created_at: created_at, updated_at: updated_at)
    end 
  end 
end 

namespace :import do 
  desc "imports invoices from a csv file"
  task :invoice => :environment do 
      CSV.foreach("lib/seeds/invoices.csv") do |row|
      id = row[0]
      customer_id = row[1]
      merchant_id = row[2]
      status = row[3]
      created_at = row[4]
      updated_at = row[5]
      Invoice.create(id: id, customer_id: customer_id, merchant_id: merchant_id, status: status, created_at: created_at, updated_at: updated_at)
    end 
  end 
end 

namespace :import do 
  desc "imports invoice_items from a csv file"
  task :invoice_item => :environment do 
      CSV.foreach("lib/seeds/invoice_items.csv") do |row|
      id = row[0]
      item_id = row[1]
      invoice_id = row[2]
      quantity = row[3]
      unit_price = row[4]
      created_at = row[5]
      updated_at = row[6]
      InvoiceItem.create!(id: id, item_id: item_id, invoice_id: invoice_id, quantity: quantity, unit_price: unit_price, created_at: created_at, updated_at: updated_at)
    end
  end 
end 

namespace :import do 
  desc "imports transactions from a csv file"
  task :transaction => :environment do 
      CSV.foreach("lib/seeds/transactions.csv") do |row|
      id = row[0]
      invoice_id = row[1]
      credit_card_number = row[2]
      credit_card_expiration_date = row[3]
      result = row[4]
      created_at = row[5]
      updated_at = row[6]
    Transaction.create(id: id, invoice_id: invoice_id, credit_card_number: credit_card_number, credit_card_expiration_date: credit_card_expiration_date, result: result, created_at: created_at, updated_at: updated_at)
    end 
  end 
end 

Вот также моя схема, если это поможет

ActiveRecord::Schema.define(version: 2018_11_27_030804) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "customers", force: :cascade do |t|
    t.string "first_name"
    t.string "last_name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "invoice_items", force: :cascade do |t|
    t.bigint "item_id"
    t.bigint "invoice_id"
    t.integer "quantity"
    t.decimal "unit_price"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["invoice_id"], name: "index_invoice_items_on_invoice_id"
    t.index ["item_id"], name: "index_invoice_items_on_item_id"
  end

  create_table "invoices", force: :cascade do |t|
    t.bigint "customer_id"
    t.bigint "merchant_id"
    t.string "status"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["customer_id"], name: "index_invoices_on_customer_id"
    t.index ["merchant_id"], name: "index_invoices_on_merchant_id"
  end

  create_table "items", force: :cascade do |t|
    t.string "name"
    t.text "description"
    t.decimal "unit_price"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.bigint "merchant_id"
    t.index ["merchant_id"], name: "index_items_on_merchant_id"
  end

  create_table "merchants", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "transactions", force: :cascade do |t|
    t.bigint "invoice_id"
    t.bigint "credit_card_number"
    t.date "credit_card_expiration_date"
    t.string "result"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["invoice_id"], name: "index_transactions_on_invoice_id"
  end

  add_foreign_key "invoice_items", "invoices"
  add_foreign_key "invoice_items", "items"
  add_foreign_key "invoices", "customers"
  add_foreign_key "invoices", "merchants"
  add_foreign_key "items", "merchants"
  add_foreign_key "transactions", "invoices"
end

И моя модель товара:

class Item < ApplicationRecord
  belongs_to :merchant
  has_many :invoice_items
  has_many :invoices, through: :invoice_items
  validates_presence_of :name, :description, :unit_price
end

Любая помощь будет высоко ценится, спасибо заранее!

1 Ответ

0 голосов
/ 29 ноября 2018

Можете ли вы проверить, что является ошибкой создания идентификатора элемента при попытке импортировать элементы счета из lib / seed / invoice_items.csv?Вы можете поместить туда некоторые записи и проверить, существует ли этот конкретный идентификатор элемента в таблице элементов.Если его нет, то он либо отсутствует в файле items.csv, либо не был вставлен во время задачи импорта элемента.

Таким образом, в основном у написанной вами задачи возникла серьезная проблема, связанная с противоречивыми данными.Мы всегда должны пытаться предотвратить это, добавляя правильное ведение журнала и применяя откат при необходимости и перехватывая исключения.Кроме того, зацикливание в CSV не является наилучшей практикой, поскольку это может занять некоторое время, когда записи в CSV становятся огромными.Поэтому попробуйте создать хеш из всех записей и сохранить его в памяти, выполнить проверки и после этого начать импорт.Каждая задача будет импортировать данные один за другим, что вызовет запрос вставки для каждого объекта.Попробуйте создать пакет записей, скажем, 1000, и выполнить массовую вставку, чтобы количество запросов было меньше, а импорт работал намного быстрее.

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