Skip to content

Instantly share code, notes, and snippets.

@bbarrows
Created February 1, 2017 01:47
Show Gist options
  • Save bbarrows/5b8a8ed9b5e64cb2f3bb46839a24a1d3 to your computer and use it in GitHub Desktop.
Save bbarrows/5b8a8ed9b5e64cb2f3bb46839a24a1d3 to your computer and use it in GitHub Desktop.
# well not sure how far u wanted that to go..
# I had to google some quick info/docs. for ex forgot method notation meaning of !
# Otherwise I think import stuff should be here. Relationships of models (which I am not 100% on but
# I would figure it out from docs if spent more time..), business logic, exceptions and
# transactions..
# I havent used rails in a while so little rusty but I know I could always get back up to speed
# really quick.. Had to learn React this week for ex..
# Hope its good enough, left a lot of comments to explain the craziness. Thanks for your time
# (If this was real code Id clean it up too..)
# Schema:
# Transaction:
# integer change_in_rubies
# integer change_in_cash
# User:
# integer rubies
# integer cash
# Game:
# Has all these user1_id, user_2, rubies_1, cash_1, rubies_2, cash_2
# Ill have to check but I thought rubies and cash on Kickback were related.. so I would prefer to just
# have one attribute like cash and convert to rubies when needed..
# Ill assume for now they are different and I cannot compute one from the other..
class Transaction < ActiveRecord::Base
belongs_to: :user
attr_accessible :change_in_rubies, :change_in_cash
# Cant remember how to store the user_id in the Transaction model so instead of reading docs
# Ill just pretend I used the right relation here
def apply!()
# So if I am getting money then should be able to just add without checking
# If I am losing money then I need to check I have enough
# so if the abs of change is > what I have raise exc
# If its 0 do nothing, Ill assume a transaction of no change would be caught beforehand
if self.change_in_rubies > 0 || self.change_in_rubies.abs < self.user.rubies
self.user.rubies += change_in_rubies
else
raise ActiveRecord::RollBack
end
if change_in_cash > 0 || change_in_cash.abs < self.user.cash
self.user.cash += change_in_cash
else
raise ActiveRecord::RollBack
end
end
# For a revert, seems like it shoudl always be fine but what if for some reason u go -? then there was an issue
# in the order the transactions were applied.. I know u can group transactions but thats in a controller or so
# I believe..
def revert!(transaction)
# could check after calc and thats maybe where u use the rollback exc...
# Ill check valid before hand. Needs to check I guess so we know if there was an out of order
# transaction replay? But if ur gaming.. well assuming a user can only play one game at a time..
# I guess transactions could potentially be batched? but u woudlnt do that here. u need to know
# what they have before and after a game..
#self.r=4
#Transaction of -4
#Transaction of +5
#If I do a revert on these transactions out of order (state is cur 4)
# I do 5 first and I am -1
#Actually you guys do cheat detection so maybe these could be applied and rolled back in non linear
if self.rubies + -transaction.change_in_rubies < 0
raise ActiveRecord::RollBack
else if self.cash + -transaction.change_in_cash < 0
raise ActiveRecord::RollBack
end
self.rubies += -transaction.change_in_rubies
self.cash += -transaction.change_in_cash
end
end
class User < ActiveRecord::Base
has_many :transactions
def deposit(change_in_rubies, change_in_cash)
if change_in_rubies > 0 && change_in_cash > 0
Transaction.create!(change_in_rubies, change_in_cash)
else
raise ActiveRecord::StatementInvalid
end
end
end
class Game < ActiveRecord::Base
# Not sure if use has_many or just pass in IDs here (whats best practice in rails)
has_one :user_1 :class_name => "User"
has_one :user_2 :class_name => "User"
has_one :transaction_1 :class_name => "Transaction"
has_one :transaction_2 :class_name => "Transaction"
# thinking about how game refund works..
# U have 2 players.. do they each get their money back? I guess logic and one (non cheater) gets money back..
# Game Join would require checking the users balance and doing a transaction if they have enough
# so join would call a user.transaction_create! or somethign with - moneys..
# Transactions could be created outside the game I guess but Im going to just do logic here
# Also getting lazy with variable naming here but I am running out of time.. and because
# I think its just asking for transaction model but had a little time so going further..
def join()
#u1 = User.find(self.user1_id)
#Id just pass in an actual user at this point prob
Transaction.transaction do
begin
#The transactions would be made liek so prob outside this model.. maybe in a controller.
#Feels weird Game having currency instead of transaction
#transaction_1 = user_1.create_transaction(rubies_1, cash_1);
#transaction_2 = user_2.create_transaction(rubies_2, cash_2);
transaction_1.apply!() # Im pretty sure in ruby u dont need () if no args
transaction_2.apply!()
# I am not even checking the user balances as the transaction apply will raise exc
# but in other languages I dont think its best practice to use exception handling
# for logic. Id expect some checks to be made before this point.. if user has enough rubies etc
rescue
# Raise exception or do some other logic here.. if just raising exception
# coudl skip the rescue I guess and let whatever calls this handle the exc
end
end
# Start game
# Some code somewhere sets a variable on the game instance self.cheating_user
end
def refund
Transaction.transaction do
begin
if self.cheating_user == user_2
transaction_1.revert!() # Im pretty sure in ruby u dont need () if no args
else if self.cheating_user == user_1
transaction_2.revert!()
end
# Prob only gonna call refund if 1 user cheated.. other wise change this logic
rescue
# This could only happen if u did transactions out of order which prob wont happen from
# what Im guessing ur setup is..
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment