Skip to content

Commit

Permalink
Add mercenary employer service and queries
Browse files Browse the repository at this point in the history
  • Loading branch information
szoroh committed Apr 17, 2019
1 parent b92faf9 commit 99a77f8
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 35 deletions.
52 changes: 17 additions & 35 deletions lecture_4/homework/app/controllers/mercenaries_controller.rb
Original file line number Diff line number Diff line change
@@ -1,61 +1,43 @@
# frozen_string_literal: true

# This controller is written badly on purpose. Please refactor this
class MercenariesController < ApplicationController
def index
render json: Mercenary.where('available_from < ?', Time.now).all
render json: MercenaryQueries.available.all
end

def show
render json: mercenary, include: [:warrior]
end

def employ_worst
mercenary = MercenariesQuery.sort_available_price_ascending.first
mercenary_employer.call(mercenary)
render json: mercenary, include: [:warrior], status: 201
end

def employ_best
mercenary = Mercenary.where('available_from < ?', Time.now).order(price: :asc).first # TODO: what about experience?
clan = find_clan
building = find_building
warrior_class = clan.warriors.select('type, count(type) as warriors_count').group(:type).order('warriors_count ASC').first.class
warrior = warrior_class.create!(name: mercenary.name, clan: clan, building: building, preferred_weapon_kind: mercenary.preferred_weapon_kind, mercenary: mercenary)
create_good_weapon(mercenary)
mercenary = MercenariesQuery.sort_available_exp_descending.first
mercenary_employer.call(mercenary)
render json: warrior, include: [:mercenary], status: 201
end

def employ
return unless mercenary.available_from < Time.now
clan = find_clan
building = find_building
warrior_class = clan.warriors.select('type, count(type) as warriors_count').group(:type).order('warriors_count ASC').first.class
warrior = warrior_class.create!(name: mercenary.name, clan: clan, building: building, preferred_weapon_kind: mercenary.preferred_weapon_kind, mercenary: mercenary)
create_good_weapon(mercenary)
mercenary = MercenariesQuery.available.sample
mercenary_employer.call(mercenary)
render json: warrior, include: [:mercenary], status: 201
end

private

def mercenary
@mercenary ||= Mercenary.find(params[:id])
end

def find_building
Building.find(params[:building_id]) if params[:building_id]
def mercenary_params
params.permit(:name, :expirience, :price, :clan_id, :building_id, :warrior_id)
end

def find_clan
if params[:clan_id]
Clan.find(params[:clan_id])
else
Clan.order(warriors_count: :desc).first
end
def mercenary_employer
MercenaryEmployer.new(mercenary_params)
end

def create_good_weapon(mercenary)
case mercenary.preferred_weapon_kind
when :melee
Weapons::Katana.create!(warrior: mercenary.warrior, range: 2, damage: 25)
when :ranged
Weapons::Musket.create!(warrior: mercenary.warrior, range: 40, damage: 10)
else
# TODO: some default?
end
def mercenary
@mercenary ||= MercenaryQueries.find_by_id(params[:id])
end
end
4 changes: 4 additions & 0 deletions lecture_4/homework/app/models/warrior.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ def attack
def null_weapon_check
weapon || NullWeapon.new
end

def mercenary_null_check
mercenary || NullMercenary.new
end
end
19 changes: 19 additions & 0 deletions lecture_4/homework/app/nulls/null_mercenary.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

class NullMercenary
def name
'Name has not been initialized'
end

def preffered_weapon_kind
'melee'
end

def available_from
nil
end

def price
nil
end
end
7 changes: 7 additions & 0 deletions lecture_4/homework/app/queries/buildings_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class BuildingsQuery
def self.find_by_id(id = nil, relation: Building)
id.nil? ? relation.first : relation.find(id)
end
end
7 changes: 7 additions & 0 deletions lecture_4/homework/app/queries/clans_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_literal_string: true

class ClansQuery
def self.find_by_id(id = nil, relation: Clan)
id.nil? ? relation.order(warriors_count: :desc).first : relation.find(id)
end
end
19 changes: 19 additions & 0 deletions lecture_4/homework/app/queries/mercenaries_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_literal_string: true

class MercenariesQuery
def self.find_by_id(id = nil, relation: Mercenary)
id.nil? ? relation.first : relation.find(id)
end

def self.sort_exp_descending(relation: Mercenary)
relation.order(expirience: :desc)
end

def self.sort_available_exp_descending(relation: available)
relation.order(expirience: :desc)
end

def self.sort_available_price_ascending(relation: available)
relation.order(price: :asc)
end
end
16 changes: 16 additions & 0 deletions lecture_4/homework/app/queries/warriors_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal :true

class WarriorsQuery
def self.find_by_id(id = nil, relation: Warrior)
id.nil? ? relation.first : relation.find(id)
end

def self.belonging_to_clan(clan_id:, relation: Warrior)
relation.where(clan_id: clan_id)
end

def self.get_class(relation: Warrior)
relation.warriors.select('type, count(type) as warriors_count')
.group(:type).oreder('warriors_count ASC').first.class
end
end
7 changes: 7 additions & 0 deletions lecture_4/homework/app/queries/weapons_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class WeaponsQuery
def self.find_by_id(id = nil, relation: Weapon)
id.nil? ? relation.first : relation.find(id)
end
end
42 changes: 42 additions & 0 deletions lecture_4/homework/app/services/mercenary_employer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_literal_string: true

class MercenaryEmployer
def initialize(mercenary_params)
@params = mercenary_params
end

def self.call(mercenary)
clan = find_clan
building = find_building
warrior_class = WarriorQuery.get_class
warrior_class.create(name: mercenary.name,
clan: clan,
building: building,
preffered_weapon_kind: preffered_weapon_kind,
mercenary: mercenary)
create_good_weapon(mercenary)
end

private

attr_reader :params

def find_building
BuildingsQuery.find_by_id(params[:building_id])
end

def find_clan
ClansQuery.find_by_id(params[:clan_id])
end

def create_good_weapon(mercenary)
case mercenary.preferred_weapon_kind
when :melee
Weapons::Katana.create!(warrior: mercenary.warrior, range: 2, damage: 25)
when :ranged
Weapons::Musket.create!(warrior: mercenary.warrior, range: 40, damage: 10)
else
NullWeapon.new
end
end
end

0 comments on commit 99a77f8

Please sign in to comment.