Topic: Need help with prizes system

I have an app where users can win points for themselves by completing tasks.  I need to now figure out a way for them to "spend" these points for specific items.  I need to create the ITEMS but I also need to figure out the process for spending..

What I am looking for is models/ relationships and basic structure.  I can code it just having a brain block on how to get this done.


thoughts?

EDIT - I could also see this as a Prizes system... Just need a little direction

Re: Need help with prizes system

I'd keep prizes together with tasks that earn them.

Is this a true statement:

Users complete tasks
Users earn prizes by completing tasks
Users spend prizes

What do the existing relationships look like for Users and Tasks?

Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: Need help with prizes system

Right now User has_many codes. redemptions

What works right now is that a User generates a Code which he/she then shares with friends. The code is then used by a friend to receive a free gift. User creates code, shares it with friends, friends redeem code and a Redemption is given to the Code creator. so if I share a code on facebook and 25 people use that code, I have 25 points. Points are easy: Redemptions.count

What I need to build:

Now that I have 25 points I can redeem/spend these points on free stuff. offered by the app. So say I got a free tube of toothpaste for 25 points, I could click a button (from the user perspective) and 25 points would be deducted from my account. For simplicities sake, at this point all I would need to do is email an app admin to handle the delivery of the tube of toothpaste.

With this in mind it seems like I need a Rewards model. I am not sure if it has any relationships though because they don't belong to a user, they don't belong to redemptions... It seems like I should use Rewards#index to list all rewards with a corresponding button that will submit a form to deduct Redemptions from my user...

Does this help clear up what I am trying to achieve?

The drawback there is that we then don't get to keep a running total of the redemptions a user has made.  Which although not imperative, would be nice to know.

Re: Need help with prizes system

I think your at a point where you have to start considering performance. You could easily devise a series of relationships involving Rewards, so that you could maintain the running total.  but you'd be adding extra indexes and runtime overhead,  just to keep your coding more elegant.

Or you could go for less elegant coding,  and less indexes and runtime overhead.

A middlegroud approach would be to leave Reward UNRELATED from the database standpoint,  but devise your routes so they look related from a routing standpoint.

something like

post '/users/redeem/:id/:code/:reward' => 'users#redeem'

Then in users_controller.rb

def redeem
   user = User.find(params[:id])
   code = Code.find(params[:code])
   reward = Reward.find(params[:reward])
   #all your logic to redeem the reward, send email etc.
   #nothing prevents you from adding a redemption count to the user table,  and incrementing 
   # here in this action, I don't think???
end
Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: Need help with prizes system

thanks for the help so far... Haven't fully made up my mind but I believe I will go with the latter option to keep performance reasonable.  As I am still trying to learn ruby/rails (first time learning a programming language, its been a solid year but...)Here are a couple questions to get me to my next step:

While I can run the call user.redemptions.count, I don't actually want to use that to keep a running total of a given users "points"

Seems that I should add a "points" field to the User model and increment the code owner's.points value.

def create
     @code = Code.find_by_code(params[:redemption][:code])
     @redemption = @code.redemptions.find_or_initialize_by_user_id(current_user.id)
     if @redemption.new_record? && @redemption.save
       redirect_to bands_url, :notice => "Redemption Successful."
     elsif @redemption
       redirect_to bands_url, :notice => "This redemption has already been used!"   
     else
       redirect_to bands_url, :notice => "There's been a problem.  We could not redeem this code."
     end
  end

This is my redemptions controller#create.  It seems that I should add a before/after_create callback (I don't think it matters in this case) and do something like:

before_create :increment_points

  def increment_points
    self.user.increment(points)
  end 

self is the redemptions, redemptions belong to users so self.user.increment(points) would increment the user.points attribute of the code creation user.

Does any of that make sense?

EDIT
Walked away and wondered if I could call the increment method on the controller before the redirect.  Something like
@code.user.increment(:points)

EDIT AGAIN
Tried the controller route and it did not appear to save any increment to the User.

EDIT AGAIN AGAIN
Ok I have been able to increment the points but to the wrong user.  ITs updating the the redeeming users points. 

before_create :increment_points

  def increment_points
    self.user.increment!(:points)
  end 

This saved like I said, just to the wrong user.

I tried modifying to:

before_create :increment_points

  def increment_points
    self.code.user.increment!(:points)
  end 

but this returns: undefined method `user' for nil:NilClass

Redemptions has_one code, code belongs to user so I figured I could write: redemption.code.user

thoughts?

Last edited by tjsherrill (2012-01-21 13:27:58)