-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add mercenary employer service and queries
- Loading branch information
Showing
9 changed files
with
138 additions
and
35 deletions.
There are no files selected for viewing
52 changes: 17 additions & 35 deletions
52
lecture_4/homework/app/controllers/mercenaries_controller.rb
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
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 |
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
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
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 |
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
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 |
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
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 |
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
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 |
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
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 |
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
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 |
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
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 |