【问题标题】:Ruby resque background CSV import does not runRuby resque 背景 CSV 导入不运行
【发布时间】:2017-01-19 11:30:16
【问题描述】:

我正在尝试使用带有 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

工人工作清单csvimport.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 中遇到的错误:

【问题讨论】:

  • 你有没有尝试过一步步调试,并尝试过实际失败的地方。请提供您的调查结果
  • 你如何在工作中获得current_user?好像没有作为参数传入。可能是工作中的nil。在这种情况下,您的验证失败,因为inventory 需要有效的user,在这种情况下它不会被保存并且什么也不会发生(除非您应该在日志中看到它,因为它会产生ValidationError 因为save!跨度>
  • @Kkulikovskis 我将控制器更改为:def import Resque.enqueue(Inventorycsvimport, params[:file], current_user.id) redirect_to root_url,注意:“库存导入作业开始。”结束,现在我得到 Exception NameError Error undefined local variable or method `current_user' for Inventorycsvimport:Class
  • @Kkulikovskis 我用代码和工作错误更新了我的原始帖子 - 感谢您的帮助!!!!!!

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


【解决方案1】:

我建议您查看 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)类它与将options 哈希定义为参数的方法相同。 file:user_id: 在 Ruby 中只是一个漂亮的东西,称为 named arguments。因此,在使用函数时,您不必经常检查参数顺序。但是,srsly,我建议你学习一些教程,你很快就会得到这个:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    相关资源
    最近更新 更多