You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ruby on Rails 7.0中当表dateto等于当前日期时执行Worker?

实现当draws表dateto等于当前日期时自动触发Worker

1. 创建处理抽奖逻辑的Worker

先生成一个负责执行抽奖核心逻辑的Worker:

# app/workers/draw_processing_worker.rb
class DrawProcessingWorker
  include Sidekiq::Worker

  def perform(draw_id)
    draw = Draw.find(draw_id)
    return if draw.has_winners? # 避免重复执行已处理的抽奖

    # 在这里编写你的抽奖逻辑,比如:
    # 抽取获奖者ID、更新draw的first_winner/second_winner字段、标记has_winners为true
    # draw.update!(first_winner: selected_user_id, second_winner: another_user_id, has_winners: true)
  end
end

2. 创建定时检查的调度Worker

这个Worker负责定时扫描到期且未处理的抽奖记录,触发上面的处理Worker:

# app/workers/draw_scheduler_worker.rb
class DrawSchedulerWorker
  include Sidekiq::Worker

  def perform
    # 查询dateto日期等于今天、且未生成获奖者的抽奖记录
    Draw.where(
      "DATE(dateto) = DATE(?)", Date.today
    ).where(has_winners: false).each do |draw|
      DrawProcessingWorker.perform_async(draw.id)
    end
  end
end

3. 配置Sidekiq Schedule定时任务

在config/sidekiq_schedule.yml中添加定时规则,设置任务执行频率:

draw_scheduler:
  cron: "0 0 * * *" # 每天凌晨0点执行一次
  class: "DrawSchedulerWorker"
  queue: default

如果需要更频繁的检查(比如每分钟扫描一次),可以把cron改为:

draw_scheduler:
  cron: "* * * * *" # 每分钟执行一次
  class: "DrawSchedulerWorker"
  queue: default

4. 让Sidekiq加载定时任务配置

在config/initializers/sidekiq.rb中添加配置,确保Sidekiq启动时加载定时任务:

Sidekiq.configure_server do |config|
  config.on(:startup) do
    Sidekiq.schedule = YAML.load_file(File.expand_path("../sidekiq_schedule.yml", __dir__))
    Sidekiq::Scheduler.reload_schedule!
  end
end

5. 关键注意事项

  • 重复执行防护:利用has_winners字段判断抽奖是否已处理,避免同一记录被多次触发
  • 时间精度调整:如果需要精确到时分秒的触发,可将查询条件改为dateto <= Time.current,同时搭配更高频率的cron规则
  • 异常处理:可在Worker中添加rescue块捕获异常,防止单个抽奖处理失败导致整个调度任务中断
  • 时区一致性:确保Rails应用时区与Sidekiq运行时区一致,避免时间判断偏差

内容的提问来源于stack exchange,提问作者Javier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 04:36:18