Как массово создавать с помощью smarter_csv для API - Ruby на Rails - PullRequest
0 голосов
/ 21 июня 2020

Извините, если сомнения очень основательные c, но я новичок в этом. Мне это нравится, но из-за работы по дому я практически один.

Я искал в inte rnet примеры создания нескольких продуктов с файлом CSV с использованием драгоценного камня smarter_csv ДЛЯ API, и у меня нет что угодно.

Я действительно не знаю, то же самое, что создание для API или нет.

Если вы можете мне чем-то помочь, я был бы очень признателен.

Моя таблица следующая, куда я хочу вставить данные.

 create_table "products", force: :cascade do |t|
    t.string "sku"
    t.string "origin_country"
    t.string "hs_code"
    t.integer "weight"
    t.string "value"
    t.string "description"
    t.string "name"
    t.string "category"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.bigint "seller_id"
    t.string "width"
    t.string "length"
    t.string "height"
    t.index ["seller_id"], name: "index_products_on_seller_id"
  end

А для создания в контроллере это следующее:

def create
  seller_id = @current_user.sellers.first.id
  @product = Product.new(product_params.merge(seller_id: seller_id))
  if @product.save
    api_response({}, 'SUCCESS', ['Product created'])
  else
    api_response({}, 'ERROR', [@product.errors], 422)
  end
end

И маршрут, я знаю, может быть, это

 post '/product/upload', to: 'products#upload'

Есть ли у вас какие-нибудь предложения для меня?

Спасибо заранее.

1 Ответ

0 голосов
/ 21 июня 2020

Так как обработка CSV может занять некоторое время, вам следует добавить его в очередь обработки и обрабатывать в фоновом режиме, вы сразу же ответите на запрос, указав идентификатор объекта в очереди, пользователь может позже вызвать другую конечную точку API с этим идентификатором, чтобы проверить статус обработки (или любые ошибки, если таковые были).

Вы можете использовать что-то вроде ActiveStorage для хранения загруженного файла и чего-то еще например, delayed_job или sidekiq для обработки файла в фоновом режиме. Вам также необходимо сохранить связанный seller_id вместе с файлом и его статусом.

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

Product.transaction do
  queue_object.update!(status: 'PROCESSING', message: "Your CSV file is being processed.")

  seller_id = queue_object.seller_id
  seller = Seler.find(seller_id);

  # I'm using the standard ruby CSV lib
  CSV.foreach(queue_object.file_path, 'r', headers: true).with_index do |row, i|
    # Call it with `!` so it raises an exception if validation fails, causing the transaction to rollback
    seller.products.create!(
      name: row['name'],
      description: row['description'],
      ...
    )
  end

# Capture validation errors
rescue ActiveRecord::RecordInvalid => e
  queue_object.update!(status: 'ERROR', message: "Error in row ##{i+1}: #{e.record.errors.to_json}")
  raise # Re-raise the error so it stops the transaction
# This will be raised if the seller is not found
rescue ActiveRecord::RecordNotFound => e
  queue_object.update!(status: 'ERROR', message: "Error in row ##{i+1}: #{e.message}")
  raise
# All other exceptions
rescue => e
  queue_object.update!(status: 'ERROR', message: "Error in row ##{i+1}: #{e.message}")
  raise
else
  # If there were no errors...
  queue_object.update!(status: 'SUCCESS', message: 'File processed successfully')
ensure
  # Delete the file here if you're not going to use it anymore
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...