Reputation: 15394
I was looking at ways to implement logic for reoccurring events. I would like to display events for the upcoming week, dependent upon their recurrence.
For example I have 2 events, one is weekly and the other is two weekly, In my view for this week I would only show the one event, but come next week there would be two showing.
So far I have my models set up like so in the migration file ready to be created
class CreateEvent
create_table :events do |t|
t.string :title
t.text :description
t.time :time_from
t.time :time_to
t.date :next_date
t.string :day
t.timestamps null: false
end
end
# An Event `has_one` Frequency
class CreateFrequency
create_table :frequencies do |f|
f.string :occurs
f.integer :event_id
t.timestamps null: false
end
end
# Was Thinking of pre populating this with Weekly and 2 weekly
# A frequency `belongs_to` Event
I am trying to keep this as simple as possible, so would I need to implement some kind of logic where I would do a calculation starting with the Events next_date
and counting the weeks passed up to today's. Not quite sure here.
Could I even go down the route of having a flag in the event model, a column called display
(boolean) and have a Rake task that will update it again using the next_date? Would that work? I am unsure of the logic there, mind.
Upvotes: 1
Views: 152
Reputation: 2297
You could store the frequency in the event table, (1 for every week, 2 for every two weeks) and then use some math to figure out if the upcoming week is an even amount of weeks after the original date, something like this:
Event.where("(extract(week from NOW())::int - extract(week from time_from)::int) % 2 = 1 OR frequency = 1")
This should grab all events that are either in its "2 week cycle" next week, or has its frequency set to 1.
Note: This will work for postgres at least, but you would need to change the data type to datetime instead of just time.
If you already have next_date stored for the events, then you can use a time range to select all events in the upcoming week:
start_date = Date.today.beginning_of_week + 7.days
end_date = start_date + 6.
@events = Event.where(next_date: start_date..end_date)
Note: I read "upcoming week" as "next week", you'd have to modify it at bit if you wish for a different behaviour.
Upvotes: 2
Reputation: 4019
I'd recommend you store the original date of the event in the database, and calculate the next event inside your model.
def frequency
case occurs
when 'weekly'
1.week
when 'biweekly'
2.week
end
end
def next_event
event_no = ((Time.now-first_event)/frequency).floor+1
return first_event + event_no*frequency
end
def event_next_week?
next_event < Time.now+1.week
end
To avoid having to do calculations every time user requests a list of events you can have a CRON job or some other sort of recurring job that would calculate the dates of next events at the beginning of each week and save them to database.
Rather than as a string, you could store the frequency as number of days or weeks.
Keeping a variable 'display' would be troublesome if you want to display events for the next 7 days and you want to stop displaying an event once it ends. Date is more flexible:
@events = Event.where('next_event > ? AND next_event < ?', Time.now, Time.now+7.days)
Upvotes: 2