user2419316
user2419316

Reputation: 331

How would you calculate expiry to update column in rails

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

Answers (1)

s.gray
s.gray

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

Related Questions