简体   繁体   中英

how to read (import) file to db use delay_job in rails

i have a class to import import_jobs.rb

require 'roo'
class ImportJob < Struct.new(:path, :name)
  def perform
    import(path, name)
  end
  #
  def import(path, name)
    spreadsheet = open_spreadsheet(path, name)
    header = spreadsheet.row(1).map!(&:downcase)

    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose].to_hash     
      potential_user = PotentialUser.find_by_id(row[:id]) || PotentialUser.new
      potential_user.attributes = row
      potential_user.save!
    end
  end
  #
  def open_spreadsheet(path,extname)
    case extname
    when ".csv" then Roo::CSV.new(path)
    when ".xls" then Roo::Excel.new(path)
    when ".xlsx" then Roo::Excelx.new(path,file_warning: :ignore)
    else raise "Unknown file type: extname"
    end
  end
end

In my View

<%= form_tag import_potential_users_path, multipart: true do %>
  <%= file_field_tag :file %>
  <%= submit_tag "Import" %>
<% end %>

In controller

def import
  if params[:file].present?
    Delayed::Job.enqueue ImportJob.new(params[:file].path, File.extname(params[:file].original_filename))
  redirect_to potential_users_path, notice: "Protential Users imported."
  else
    redirect_to potential_users_path
  end
end

When in run jobs, it display error does not exits file . Althought when i run it dont use delay_job, code ís working

[Worker(host:ubuntu pid:14362)] Job ImportJob (id=860) RUNNING
[Worker(host:ubuntu pid:14362)] Job ImportJob (id=860) COMPLETED after 2.0222
[Worker(host:ubuntu pid:14362)] Job ImportJob (id=858) RUNNING
[Worker(host:ubuntu pid:14362)] Job ImportJob (id=858) FAILED (3 prior attempts) with IOError: file /tmp/RackMultipart20151211-14238-13b7xb does not exist
[Worker(host:ubuntu pid:14362)] 2 jobs processed at 0.7092 j/s, 1 failed

Looks like temporary file is removed prior to the moment when the worker starts to process the job. I'd suggest you to copy the file to another location and then try again. Here's a chunk of code that might help:

if params[:file].present?
  original_filename = params[:file].original_filename
  new_filename = "#{File.basename(original_filename)}_new"
  new_filepath = File.join(Dir.tmpdir, new_filename)
  FileUtils.cp(params[:file].path, new_filepath)
  import_job = ImportJob.new(new_filepath, File.extname(original_filename))
  DelayedJob.enqueue(import_job)
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM