Created
February 1, 2017 01:47
-
-
Save bbarrows/5b8a8ed9b5e64cb2f3bb46839a24a1d3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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