Modeling a subscription service

0 views
Skip to first unread message

Bryan

unread,
Nov 8, 2009, 11:32:48 PM11/8/09
to pdx...@googlegroups.com
Hi,

I'm developing a Rails app where users can subscribe to a service that gives them access to certain content on the site for a period of time.  There are multiple types of subscriptions, so I have a SubscriptionType model that has a one-to-many relationship with the Subscription model.  Subscriptions are LineItems associated with Orders, and Orders are what the user actually pays for.

My problem is with the shopping cart logic. In the way I have it set up now, when the user adds a subscription to the shopping cart, a new Subscription object is created and saved to the DB. It didn't occur to me until now that users would potentially be creating a lot of objects in the DB that really don't need to be there when the user adds something to the cart but doesn't make the final purchase.

So now I'm seeing two general ways to approach this:

1.  Have the user add SubscriptionType objects to the cart and later when they checkout create the associated Subscription objects to be saved to the database.

2.  Maybe I don't need both a SubscriptionType and Subscription model and could use just one.  This would normalize the database a little bit since the purchase information (like whether the payment went through, who made the purchase, etc.) is stored in the Order model.  But it just feels like there should be a separate model for the Subscription itself. 

Either way would work, but I have a feeling there's a better or more conventional approach to this..

Thanks,
Bryan

Maher Hawash

unread,
Nov 9, 2009, 7:45:33 AM11/9/09
to pdx...@googlegroups.com
Did you consider using a state machine to transition the order through
its life cycle.

Order has_many subscriptions
Subscription belongs_to Order

Order has states (in_cart, checked_out, paid, refunded, ...etc).

The user can:
1. add subscription to cart (repeat):
creates an current_order object (if new), attaches the
subscription item, and marks Order in_cart.
2. Checks out: Order transitions to checked_out
3. Pays: Order transitions to paid
4. Requests refund (after paying): Order transitions to refunded.

And whatever other states you might choose to have.

Maher

Colin Curtin

unread,
Nov 9, 2009, 10:51:18 AM11/9/09
to pdx...@googlegroups.com
Bryan,

Is it necessary for you to have a "shopping cart" and have them
checkout with the subscription in it?

When I've worked on subscription apps, it was always just a page to
see the different subscription types, then you select a type, which
posts to a page to pay (checkout). Once they pay, you create the
subscription record for their user/account.

Otherwise, it sounds like you're on the right track. I would follow
Maher's advice and slap AASM on your subscription model, and have an
initial state of "unpaid". Then when they pay, you can put it in state
"active". Later you can write a cron to get rid of subscription
objects that aren't used.

HTH,
Colin

On Sun, Nov 8, 2009 at 8:32 PM, Bryan <bdo...@gmail.com> wrote:

Chuck Vose

unread,
Nov 9, 2009, 11:23:28 AM11/9/09
to pdx...@googlegroups.com
One counter thought is that this information you're gathering could be
valuable. Having stats about how many people tried to subscribe but
failed to do so is honestly one of the best metrics you have to see if
design changes and marketing are working for you. So depending on the
number of objects being made I wouldn't worry too much about it and
instead try to use that to your advantage. Stock MySQL and Postgres
should be able to handle hundreds of millions of rows fairly easily.

So I would second the state machine transitional model. Those unpaid's
are your paydirt when it comes to marketing and attracting
advertisers.

-Chuck

Bryan

unread,
Nov 9, 2009, 11:40:19 AM11/9/09
to pdx...@googlegroups.com
Thanks Maher,

I am using a state machine in my Subscription and SubcriptionType models, but didn't even think of adding in_cart and checked_out states. Good idea..

I'm not sure I want to change the Order model much since each subscription is a line item on an Order that can have many line items, and since the Order model is actually part of the acts_as_billable plugin (which I don't think is used often, but works rather well for me).

-Bryan

Bryan

unread,
Nov 9, 2009, 11:47:26 AM11/9/09
to pdx...@googlegroups.com
Thanks Colin.  It's possible that it's not necessary to have a cart, but I'm assuming that there will be more than one type of subscription available that the user can purchase simultaneously.  It's possible that the combination of subscription types would just be rolled up into a new subscription type that probably gives a discount, but I think I should assume the worst for now. This particular app is for baseball stats and I imagine there could be a couple of options like: "Fantasy Insider" and "Super-cool Player Projections" that aren't necessarily able to be packaged together, but which the user might want to purchase together anyway.

-Bryan


On Mon, Nov 9, 2009 at 7:51 AM, Colin Curtin <colin.t...@gmail.com> wrote:

Bryan

unread,
Nov 9, 2009, 11:53:48 AM11/9/09
to pdx...@googlegroups.com
Chuck, this is one thing that I thought of as well but figured it would be sort of a hack in lieu of writing some better analytics code.   But hey, I'm glad someone else thinks its a good idea.  I'll just do this since it's pretty much done and we don't expect (but we do hope) to get millions of subscribers.

So now I'm thinking I'll leave the two models (SubscriptionType and Subscription), modify my state machine to have a few more states like in_cart and checked_out, and reap the benefits of additional metrics.

Thanks guys

Bryan
Reply all
Reply to author
Forward
0 new messages