Ruby:如何将模型中的倒计时方法结果更新到数据表列中
Got it, let's break down how to automatically update that days column with your calculated remaining days. First, let's fix up your existing methods a bit to iron out typos and ensure they work correctly, then walk through two reliable approaches to auto-update the column.
Step 1: Refine Your Calculation Methods
First, let's clean up your existing methods (I'm guessing you had a typo with start_da...):
class Event < ApplicationRecord # Determine the starting point for the countdown def closer_to_end_date if Date.today >= start_date Date.today else start_date end end # Calculate remaining days as an integer def event_days (end_date - closer_to_end_date).to_i end end
Step 2: Auto-Update the days Column
You have two main options depending on your needs:
Option 1: Use Active Record Callbacks (Update on Save)
If you want the days column to update whenever the event record is saved (especially when start_date or end_date changes), add a callback to your model:
class Event < ApplicationRecord # ... your refined methods above ... # Trigger update before saving the record before_save :sync_remaining_days private def sync_remaining_days # Only update if the date fields changed (optional optimization) self.days = event_days if start_date_changed? || end_date_changed? end end
This works great for keeping days in sync when you edit the event's dates, but it won't update automatically as time passes (e.g., the next day, the remaining days will be wrong until you save the record again).
Option 2: Use a Scheduled Task (Daily Auto-Update)
If you need the days column to stay accurate every day without manual saves, set up a recurring task to refresh all events' remaining days. We'll use the whenever gem (a popular Rails tool for cron jobs):
- Install the gem and initialize it:
gem install whenever wheneverize .
- Add the daily task to
config/schedule.rb:
# Run at midnight every day to update all events' remaining days every 1.day, at: 'midnight' do runner "Event.refresh_all_remaining_days" end
- Add the class method to your Event model:
class Event < ApplicationRecord # ... your refined methods above ... def self.refresh_all_remaining_days # Use find_each for efficiency with large datasets find_each do |event| # update_columns skips validations/callbacks for faster updates event.update_columns(days: event.event_days) end end end
- Deploy the cron job (for production environments):
whenever --update-crontab
This ensures the days column is always up-to-date, even if no one edits the event records.
Quick Note: Do You Even Need to Store days?
If you don't need to query or sort by remaining days, you could skip storing it entirely and just call event.event_days whenever you need the value. Storing it only makes sense if you need to optimize performance for frequent queries or use the column in database-level filters.
内容的提问来源于stack exchange,提问作者Belal Kamara

