Implementing a credit-based system

Hey all, fairly new to Rails here and I am currently building my first Rails app.

I am building an app that will require users to purchase credits in order to post items on the site. These credits will be purchased in blocks of credits like 5, 10, 20, etc. (similar to istockphoto.com).

Here is how I picture setting up the credits in my app.

Credits Model - This model would determine the different credit packages (5,10,20) along with the price of each credit package.

This model would "belong to" User and the User "has many" Credits, right?

I then assume that the controller for my credits is where I would handle the logic of adding credits to the user accounts, making sure the credit is deducted when they list an item, and keeping track of how many credits a user has at any given time. I also assume that as credits are purchased, and the user needs to be emailed notification of that purchase, that logic would also live in this same controller, right?

Am I on the right track here as far as mapping out what goes where? I am really loving Rails so far, I am just having a bit of a hard time wrapping my head around where logic goes and what handles what and how they all tie in together!

I appreciate any help or feedback that you guys can give me! Thanks!

Hey all, fairly new to Rails here and I am currently building my first Rails app.

I am building an app that will require users to purchase credits in order to post items on the site. These credits will be purchased in blocks of credits like 5, 10, 20, etc. (similar to istockphoto.com).

Here is how I picture setting up the credits in my app.

Credits Model - This model would determine the different credit packages (5,10,20) along with the price of each credit package.

This model would "belong to" User and the User "has many" Credits, right?

Part of this depends on your requirements, but you could easily have 2
models: Credit (belongs_to user, and user has many credits). 1 for each one
purchased and tracks stuff like if it should expire, what it was used
for, etc...

Another model which handles whatever packages people can purchase.

I then assume that the controller for my credits is where I would handle the logic of adding credits to the user accounts, making sure the credit is deducted when they list an item, and keeping track of how many credits a user has at any given time. I also assume that as credits are purchased, and the user needs to be emailed notification of that purchase, that logic would also live in this same controller, right?

I would have very very little in the controller, probably as simple as

def purchase    @package = Package.find params[:id]    current_user.purchase @package end

Similarly, at the point where the user uploads some content, i doubt
I'd do much more than call a method on the user (and the logic of
removing credits etc... would live there).

You might want to do some of the emaily stuff via an observer. There's a saying out there which is a good rule of thumb: 'skinny
controllers, fat models'

Fred

Frederick, Thanks for the clarification. I see what you are saying with making sure there is as little logic as possible in the controllers.

I also see what you are saying with having 2 separate controllers (1 for the credits and 1 for the packages). I had not thought about it that way before, but that does seem to make more sense to me.

For some reason, I keep thinking that I have to have as few models and controllers as possible, when I think I should be concentrating more on building it the way it makes the most sense.

--Cory

Frederick, Thanks for the clarification. I see what you are saying with making sure there is as little logic as possible in the controllers.

I also see what you are saying with having 2 separate controllers (1 for the credits and 1 for the packages). I had not thought about it that way before, but that does seem to make more sense to me.

I'm not even sure if there is a credits controller - you never
directly interact with them : you buy packages, and then you perform
uploads or other actions (which as a side effect use a credit). The only thing I can think of is a page which showed you how many
credits you have or other audit traily types of information (but that
could easily just boil down to some text on the 'my account' page).

Fred

Yeah sorry! I meant 2 separate MODELS not controllers! That second cup of coffee hasn't quite kicked in yet.

--Cory

Hey all, fairly new to Rails here and I am currently building my first

Rails app.

I am building an app that will require users to purchase credits in

order to post items on the site. These credits will be purchased in

blocks of credits like 5, 10, 20, etc. (similar to istockphoto.com).

Here is how I picture setting up the credits in my app.

Credits Model - This model would determine the different credit

packages (5,10,20) along with the price of each credit package.

Is a Credits model necessary? Would it be easier to have a credits attribute (int) on the User model, and increment/decrement accordingly?

This model would “belong to” User and the User “has many” Credits,

right?

I then assume that the controller for my credits is where I would

handle the logic of adding credits to the user accounts, making sure

the credit is deducted when they list an item, and keeping track of

how many credits a user has at any given time. I also assume that as

credits are purchased, and the user needs to be emailed notification

of that purchase, that logic would also live in this same controller,

right?

How about a Package model (which would hold the price for the package, number of credits, and any other attributes you’d like). Then define a method on the User model called “apply_credits(number)” which takes the number of credits to apply as an argument. Then, when they purchase the package, do “@user.apply_credits(@package.num_credits)” (in the controller that’s handling the purchase) to increment the credits.

You may want to watch a few Railscasts (http://railscasts.com/episodes/archive), especially #4 - Move Find into Model. It’s a good idea to have fat models and skinny controllers–move all your complex logic to the model and keep the controller terse.

Quite possibly, I think the key point is whether the audit trail is important: do you need to know where the credits have come from (for a given user), what they spent them on etc.. ie do you want to be able to track them?

Fred