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

Rails应用每24小时自动切换图片:实例变量传递及调度方案咨询

解决方案

核心问题分析

你当前的思路存在逻辑误区:如果在控制器中调用rake任务,确实会在每次请求时都执行切换逻辑,完全达不到“每24小时自动切换”的目的。正确的做法应该是把「每日选图标记」的逻辑交给后台定时任务执行,控制器只负责「读取已选好的当日图片」。

重构方案:用模型类方法实现逻辑复用

我们可以将选图、标记的逻辑抽离到Newspaper模型的类方法中,既方便定时任务调用,也能让控制器直接读取结果,同时解决6张图片循环展示的问题。

1. 重构Newspaper模型

class Newspaper < ApplicationRecord
  # 筛选未被标记为已展示的图片
  scope :undone, -> { where(done: false) }

  # 选择当日展示图片并标记为已展示,自动循环重置
  def self.select_todays_paper
    paper = undone.first
    return unless paper

    paper.update(done: true)
    # 当所有图片都被标记过,重置状态实现循环展示
    update_all(done: false) if undone.empty?
    paper
  end

  # 获取当前正在展示的图片(最近被标记的)
  def self.current_paper
    order(updated_at: :desc).find_by(done: true)
  end
end

2. 简化定时任务(rake/Sidekiq)

修改原rake任务,直接调用模型类方法:

namespace :images do
  desc "每日自动选择展示的图片"
  task select_today: :environment do
    Newspaper.select_todays_paper
  end
end

用Whenever配置每日定时执行(比如凌晨0点):

# config/schedule.rb
every 1.day, at: '00:00' do
  rake 'images:select_today'
end

3. 控制器读取当日图片

控制器只需要调用current_paper获取已选好的图片,无需执行切换逻辑:

class GalleriesController < ApplicationController
  def index
    @todays_paper = Newspaper.current_paper
    # 首次运行时如果还没有当日图片,手动触发一次选图
    @todays_paper ||= Newspaper.select_todays_paper
  end
end

为什么这样做?

  • 定时任务每日仅执行一次选图标记,避免了每次请求重复执行逻辑
  • 控制器只做读取操作,性能更优,职责更清晰
  • 模型类方法统一了逻辑,避免代码重复
  • 新增了循环重置逻辑,解决6张图片全部展示后无图可选的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:01:03