Simple User and Plan associations

I’m adding payment plans to an app. The requirements are simple: each User has resource limits in the app (max. number of photos) and is moved automatically to the correct Plan as they add or remove photos.

When a User moves to a different Plan the change is pushed to the appropriate Stripe customer via the API and they are billed at the end of the month accordingly.

Since a User does not explicitly change their plan themselves, nor can they be on more that one plan at once I don’t see the need for a Subscription model. I’m keeping it simple with a one-to-one between User and Plan.

In fact the only reason I have a Plan model at all is to avoid having to call the Stripe API every time I move a User to a different Plan.

The associations I have are:

# user.rb
class User < ActiveRecord::Base
  has_many :photos
  belongs_to :plan
end  
# plan.rb
class Plan < ActiveRecord::Base
  has_many :users
end

This is a multi-tenanted app and since User is the tenant somehow it doesn’t feel right for it to belongs_to another object.

Do you think I’ve over-simplified this? Is there a better way to associate User and Plan?

I’ve built a handful of SaaS apps, and I’ve always eventually wanted to dissociate subscriptions and plans.

This seems okay now, so it’s not a bad idea to start with it. But I’d put $5 on you eventually creating a Subscription model. :smile:

One example: right now, every user has a plan. And having a plan means they are subscribed. What if you want to be able to offer a free plan to internal employees (like you)?

2 Likes

Thanks @benorenstein. I agree, I may have to add a Subscription model at some point when the app becomes more complex but I’m keen to keep things as simple as possible to start with.

We have a free plan at $0 and every new User starts on that plan. As they use more resources they are moved to the appropriate paid plan. It would be easy enough in the future to make this conditional on a User attribute like type.

Does that sound messy?

One reason I can think of to use a Subscription model right now is to keep a timeline of the movement from plan to plan. The only way to check this at the moment is to trawl back through a user’s versions.