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

如何在指定时间自动处理数据?及Rails应用每日生成当日Top5故事需求

Hey there! Let's tackle your two questions—scheduled data automation and building that daily Top 5 stories feature for your Rails app—step by step.

Scheduled Data Automation & Daily Top 5 Stories for Your Rails App

Part 1: Implementing Scheduled Data Processing

First, for running tasks at a specific time in Rails, you’ve got two reliable options:

  • System-level cron (Linux/macOS) or Task Scheduler (Windows): Stick to native tools if you want to avoid extra gems.
  • The whenever gem: A Rails-friendly wrapper for cron that lets you write scheduled tasks in Ruby syntax (highly recommended for readability and maintainability).

Part 2: Building the Daily Top 5 Stories Feature

Let’s walk through the exact steps to replace your global Top 5 with a daily-updated version:

Step 1: Add Logic to Calculate Daily Top Posts

Add a class method to your Post model to fetch the top 5 posts from a given day. Adjust this based on how you track likes:

# app/models/post.rb
class Post < ApplicationRecord
  # Option 1: If you have a cached `likes_count` column (updated every time a like is added)
  def self.daily_top_5(date = Date.today)
    where(created_at: date.beginning_of_day..date.end_of_day)
      .order(likes_count: :desc)
      .limit(5)
  end

  # Option 2: If you need to count likes in real-time (using a `Like` model that belongs to `Post`)
  # def self.daily_top_5(date = Date.today)
  #   joins(:likes)
  #     .where(likes: { created_at: date.beginning_of_day..date.end_of_day })
  #     .group(:id)
  #     .order('COUNT(likes.id) DESC')
  #     .limit(5)
  # end
end

Step 2: Create a Scheduled Job to Cache/Save Daily Top Posts

Using Rails Jobs keeps your code organized and lets you leverage background processing if needed. First, generate a job:

rails generate job DailyTopStories

Choose one of these two options based on your needs:

Option A: Cache the Results (Fast & Simple)

Great for quick reads without needing historical data:

# app/jobs/daily_top_stories_job.rb
class DailyTopStoriesJob < ApplicationJob
  queue_as :default

  def perform
    today = Date.today
    Rails.logger.info "Calculating daily top 5 stories for #{today}"
    
    top_posts = Post.daily_top_5
    # Store in Rails cache with a date-specific key
    Rails.cache.write("daily_top_posts_#{today}", top_posts, expires_in: 1.day)
    
    Rails.logger.info "Successfully cached daily top posts: #{top_posts.pluck(:id).join(', ')}"
  end
end

Option B: Save to a Dedicated Table (For Historical Data)

Use this if you want to keep records of past daily Top 5s:

# First generate a model to store daily rankings
rails generate model DailyTopPost post:references rank:integer date:date
rails db:migrate

Then update the job:

# app/jobs/daily_top_stories_job.rb
class DailyTopStoriesJob < ApplicationJob
  queue_as :default

  def perform
    today = Date.today
    Rails.logger.info "Calculating daily top 5 stories for #{today}"
    
    # Clear existing entries for the day to avoid duplicates
    DailyTopPost.where(date: today).destroy_all
    
    # Save each top post with its rank
    Post.daily_top_5.each_with_index do |post, index|
      DailyTopPost.create!(post: post, rank: index + 1, date: today)
    end
    
    Rails.logger.info "Successfully saved daily top posts for #{today}"
  end
end

Step 3: Schedule the Job to Run Daily

We’ll use the whenever gem for this (it’s way simpler than writing raw cron):

  1. Add the gem to your Gemfile:
# Gemfile
gem 'whenever', require: false
  1. Install the gem and initialize the schedule file:
bundle install
wheneverize .
  1. Edit config/schedule.rb to set your desired run time (e.g., 23:59 to capture all posts from the day):
# config/schedule.rb
every 1.day, at: '23:59' do
  runner "DailyTopStoriesJob.perform_now"
end
  1. Update your server’s cron tab:
whenever --update-crontab

If you prefer not to use whenever, add this cron command directly to your system (replace /path/to/your/app with your Rails app’s path):

59 23 * * * cd /path/to/your/app && bundle exec rails runner "DailyTopStoriesJob.perform_now"

Step 4: Update Your Controller & View

Modify your controller to fetch the daily Top 5:

For Cache Option:

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def top_stories
    # Fallback to real-time calculation if cache is missing (e.g., first run)
    @posts = Rails.cache.read("daily_top_posts_#{Date.today}") || Post.daily_top_5
  end
end

For Dedicated Table Option:

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def top_stories
    @posts = DailyTopPost.where(date: Date.today).order(rank: :asc).pluck(:post)
  end
end

Your existing view code doesn’t need major changes—since @posts now holds the day’s Top 5, this will work just fine:

<% posts.each_with_index do |post, index| %>

...
<% end %>

Quick Tips

  • Server Time: Double-check your server’s timezone to ensure the job runs at the correct time.
  • Logging: The job includes logger statements to help you debug if things go wrong. Check log/production.log (or development log) for details.
  • Cache Backend: If you’re using caching, make sure you have a backend like Redis or Memcached set up (Rails defaults to file-based cache, which isn’t ideal for production).

内容的提问来源于stack exchange,提问作者Noor Ali Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:16:23