Ruby resque后台CSV导入无法运行

时间:2016-09-12 04:23:39

标签: ruby-on-rails ruby csv redis resque

我正在尝试使用带有resque的后台作业导入CSV文件。它似乎运行但没有任何反应。当我没有使用resque时,导入工作正常(我正在使用resque,因为一些导入很大,我想转移到后台工作,测试它的一个小的2行csv)

非常感谢任何帮助,非常感谢! (也是我的初学者,所以请愚蠢的任何帮助:))

inventories_controller.rb:

  def import
    Resque.enqueue(Inventorycsvimport, params[:file], current_user.id)
    redirect_to root_url, notice: "Inventory import job started."
  end

worker JOB inventorycsvimport.rb:

class Inventorycsvimport
  @queue = :Inventorycsvimport
  def self.perform()
    Inventory.destroy_all(user_id: current_user.id)
    Inventory.import(params[:file], current_user.id)
  end
end

导入类inventory.rb:

class Inventory < ApplicationRecord
    belongs_to :user

  def self.import(file, user_id)
    allowed_attributes = [ "user_id", "id","description","part_number","price","created_at","updated_at", "alternate_part_number", "condition_code", "qty", "mfg_code", "serial_number", "part_comments"]
    spreadsheet = open_spreadsheet(file)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      inventory = find_by_id(row["id"]) || new
      inventory.attributes = row.to_hash.select { |k,v| allowed_attributes.include? k }
      inventory.user_id = user_id
      inventory.save!
    end
  end

  def self.open_spreadsheet(file)
    case File.extname(file.original_filename)
      when ".csv" then Roo::CSV.new(file.path)
      when ".xls" then Excel.new(file.path, nil, :ignore)
      when ".xlsx" then Excelx.new(file.path, nil, :ignore)
    else raise "Unknown file type: #{file.original_filename}"
    end
  end
end

这是我在JOB中遇到的错误:

enter image description here

1 个答案:

答案 0 :(得分:0)

我建议您查看Sidekiq文档。据我所知,所有传入的参数都可以通过options哈希在作业中使用。所以当传递参数时,你需要以某种方式在另一端接收它。

在控制器中试试这个:

  def import
    Resque.enqueue(Inventorycsvimport, file: params[:file], user_id: current_user.id)
    redirect_to root_url, notice: "Inventory import job started."
  end

这就在你的工作中:

  def self.perform
    Inventory.destroy_all(user_id: options[:user_id])
    Inventory.import(options[:file], options[:user_id])
  end

你的代码没有多大意义(我建议一些编程教程(codecademy.com可能是一个好的开始),因为你试图在不同的范围内使用变量。你拥有的current_user你的控制器不是你可以在任何地方访问的神奇变量。它来自你的控制器类继承的ActionController::BaseApplicationController类下定义的辅助方法。

由于Job类与控制器类无关,因此无法直接访问控制器的任何方法或变量。因此,在定义方法时,您有parameters这样的选项,允许您将这些变量传递到不同的类和范围。

在这种情况下可能令人困惑的是作业的perform方法,您不必将options声明为参数,因为它使用的是ActiveJob(或Sidekiq 1)})引擎盖下的类具有相同的方法,其中options哈希被定义为参数。 file:user_id:在Ruby中只是一个名为named arguments的东西。因此,在使用函数时,您不必经常检查参数顺序。但是srsly,我建议你做一些教程,你马上就会得到这个:)

相关问题