Skip to content

Instantly share code, notes, and snippets.

@gogogarrett
Last active August 29, 2015 13:57
Show Gist options
  • Select an option

  • Save gogogarrett/9563565 to your computer and use it in GitHub Desktop.

Select an option

Save gogogarrett/9563565 to your computer and use it in GitHub Desktop.
basic idea for implementing a state machine. Not tested or throught out in much detail.. but meh.
module Persistance
class Trade < ActiveRecord::Base
validates :item_id, :actor_id, presence: true
def state
super.to_s
end
end
end
module Policy
class Trade
def initialize(item, requester, quanity)
@item, @requester, @quanity = item, requester, quanity
end
def valid?
items.size >= quanity && has_enough_funds?(requester, items)
end
private
attr_reader :item, :requester, :quanity
def items
Item.where(item_type: item.class)
end
def has_enough_funds(requester, items)
requester.funds == items.map(&:cost)
end
end
end
module Service
class CreateTrade
def initialize(item, requester)
@item, @requester = item, requester
end
def call
Persistance::Trade.create(item_id: item.id, actor_id: requester.id)
StateKeeper.new(item, requester).requested
end
private
attr_reader :item, :requester
end
end
class StateKeeper
def initialize(item, actor)
@item, @actor = item, actor
end
def requested!
transision_to(:request)
end
def complete!
transision_to(:accepted)
end
def current_state
Persistance::Trade.where(item_id: item.id, actor_id: actor.id).state
end
private
attr_reader :item, :actor
def transision_to(state=nil)
Persistance::Trade.where(item_id: item.id, actor_id: actor.id).update(state: state)
end
end
class TradeRequest # this could be a controller action I suppose
def self.trade(item, requester, quanity)
if Policy::Trade.new(item, requester, quanity).valid?
Service::CreateTrade.new(item, requester).call
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment