Ruby on Rails结合Sidekiq实现删除请求入队问题求助
解决Sidekiq传递ActiveRecord实例的参数问题
问题根源
Sidekiq 使用 JSON 序列化队列参数,而 ActiveRecord 模型实例包含大量无法被 JSON 序列化的复杂属性(比如关联对象、内部状态),直接传递实例会触发序列化错误。正确的做法是传递可序列化的简单类型,比如模型的 ID。
修改代码示例
1. 控制器 destroy 方法修改
把原来传递 Book 实例的代码改成传递 ID:
# app/controllers/books_controller.rb def destroy @book = Book.find(params[:id]) # 传递书籍ID到队列,而非模型实例 BookDeleteWorker.perform_async(@book.id) redirect_to books_path, notice: '删除请求已加入队列,将稍后执行' end
2. Worker 类修改
在 perform 方法中接收 ID,再查找模型执行删除操作,同时处理记录已被删除的情况:
# app/workers/book_delete_worker.rb class BookDeleteWorker include Sidekiq::Worker # 如果你的项目有BaseWorkerJob基类,改成继承它即可 # class BookDeleteWorker < BaseWorkerJob def perform(book_id) # 使用find_by避免记录已删除时抛出ActiveRecord::RecordNotFound错误 book = Book.find_by(id: book_id) return unless book book.destroy end end
额外提示
- 若你的
BaseWorkerJob已经包含Sidekiq::Worker模块,直接让业务 Worker 继承它即可,无需重复引入。 - 队列执行时,原记录可能已被其他操作删除,用
find_by替代find可以避免不必要的错误日志。
内容的提问来源于stack exchange,提问作者Mohamed Medhat
相关产品推荐
相关产品推荐

