如何在Rails控制器中向Sidekiq Worker传递params[:file]参数
问题原因
Sidekiq 的任务参数必须是可序列化的数据类型(比如字符串、数字、哈希等),而 ActionDispatch::Http::UploadedFile 是复杂对象,无法直接被序列化,传递给 Worker 时会被转换成字符串形式,导致无法正常操作文件。
解决步骤
核心思路是先把上传的文件保存到本地临时目录,再将文件路径传递给 Worker,Worker 通过路径读取文件进行处理。
1. 修改 Controller 代码
先创建临时存储目录(确保目录存在),将上传的文件保存到该目录,再把文件路径传给 Worker:
class CsvController < ApplicationController def read_csv # 定义临时存储路径 upload_dir = Rails.root.join('tmp', 'uploads') FileUtils.mkdir_p(upload_dir) unless Dir.exist?(upload_dir) # 生成唯一文件名,避免冲突 file_path = upload_dir.join("#{SecureRandom.uuid}_#{params[:file].original_filename}") # 保存上传的文件到本地 File.open(file_path, 'wb') do |file| file.write(params[:file].read) end # 传递文件路径给 Worker CsvWorker.perform_async(file_path.to_s) end end
2. 修改 Worker 代码
通过接收的文件路径读取文件,处理完成后可以选择删除临时文件:
class CsvWorker include Sidekiq::Worker def perform(file_path) # 读取并处理 CSV 文件 csv_data = SmarterCSV.process(file_path) # 这里添加你的业务逻辑,比如将数据存入数据库等 # 可选:处理完成后删除临时文件 File.delete(file_path) if File.exist?(file_path) end end
注意事项
- 确保
tmp/uploads目录有读写权限,避免保存文件失败 - 如果处理大文件,考虑使用云存储代替本地临时目录,避免服务器磁盘占用过高
- 若 Worker 处理失败,临时文件可能残留,可以定时清理
tmp/uploads目录的过期文件
内容的提问来源于stack exchange,提问作者Chirag Rathod
相关产品推荐
相关产品推荐

