Reputation: 331
I'm trying to figure out the right approach for calculating the remainder days of a user subscription.
For example; user signs up December 25, 2013 for a month and unsubscribed December 29, 2013. Even though he unsubscribed 4 days after subscribing, his subscription should run on PLAN A for the next 27 days (31 day based month).
I'm thinking I would be using the created_at and updated_at of subscription model. So far I got to
**MODEL: subscription.rb
class Subscription < ActiveRecord::Base
before_save :set_expiry_date
def set_expiry_date
@remaining_days = Subscription.calculate(:created_at - Date.today)
Subscription.expiry = '@remaining_days'
Subscription.save
end
end
Something like that but I'm missing something here and this might be an ugly approach. I'm guessing this gives anyone who can help small understanding what I'm after.
I would then run a rake as cron each day at 23:59 that removes 1 (day) from Subscription.expiry number in there and when it finds a 0, it would update something. That's another question though but I placed the stuff about the rake cron so you see where I'm heading with this.
Upvotes: 2
Views: 1615
Reputation: 188
If this were my project, I would take a different approach. I would set subscription expiry to the actual expiry date rather than a decrementing integer. That makes less work for the cron and also feels like good date practice . . . you get the benefit of persisting expiration dates after the expiration, which might be handy for later data analysis. What if there is a bug in your program or your cron fails to run? By persisting the date, you can do some detailed homework or rerun your crons against a specific cohort.
If I needed to know how many days were remaining on the subscription for UI or for API responses, I could call a method on the subscription class that looks something like the remaining_days method below:
def set_expiry_date
#automatically adds a month
#http://ruby-doc.org/stdlib-2.1.0/libdoc/date/rdoc/Date.html#method-i-next_month
Subscription.expiry_date = Subscription.created_at.next_month
Subscription.save
end
def remaining_days
expired? ? 0 : (Date.today - Subscription.expiry_date).to_i
end
def expired?
(Date.today - Subscription.expiry_date).to_i <= 0
end
def expired_today?
Date.today == Subscription.expiry_date
end
Then, my daily cron that does something on expiration (send email beseeching the customer to come back?) would just look for subscriptions where expired_today? == true. My cron would then also ignore subscriptions that expired before today or are yet to expire.
Upvotes: 4