Conversation
update respository
after second lecture
Classes number 3 compare
lcture 4
Add lecture 5 slides
| validates :granary, presence: true, | ||
| numericality: { greater_than_or_equal_to: 0, only_integer: true } | ||
| validates :name, presence: true | ||
| validates :granary, :siege_ability, :horse_units, :infantry_units, presence: true, |
There was a problem hiding this comment.
siege_ability zostało u Ciebie zaimplementowane jako obliczalny atrybut, więc nie ma co go w bazie przechowywać :) Oczywiście optyamlizacyjnie to nie brzmi najlepiej, jeśli chcielibyśmy to optymalizować to możnaby np. raz dziennie przy pomocy jakiejść kolejki(np. Sidekiq, ActiveJob, Resque) odświeżać ten atrybut, albo usunąć ten atrybut i w serializerze scachować wywołanie serwisu, żeby nie latał ciągle jak głupi :D
| module Warriors | ||
| class Hussar < Warrior | ||
| attribute :preferred_weapon_kind, :string, default: :ranged | ||
| before_create :give_him_horse |
There was a problem hiding this comment.
Obecne API chyba pozwala na zmianę tego atrybutu, przez co można zabrać husarzowi konia :( możnaby to rozwiazać walidacją, gdzie horse zawsze musi być true i dodatkowo zamienić ten callback na before_commit, co nie jest ładne dla klienta bo niby wszystko jest ok, a jednak, zmiana którą podał się nie wprowadza :<
| has_many :warriors | ||
|
|
||
| def type | ||
| object.type.split('::')[1] |
There was a problem hiding this comment.
Metoda demodulize jest trochę mądrzejsza :D
| end | ||
|
|
||
| def warriors_alive | ||
| object.warriors.alive.count |
There was a problem hiding this comment.
Tutaj mamy problem z n+1. Można by go rozwiązać przez bazodanowe wcześniejsze doincludowanie(#includes) wojowników do query po budynki, użycie select zamiast where do odfiltrowania żywych wojowników i użycie metody .length do liczenia :)
There was a problem hiding this comment.
NP.:
object.warriors.select { |w| !w.death_date }.length| end | ||
|
|
||
| def call | ||
| @params_key.to_i == 0 ? @warriors.dead : @warriors.alive |
There was a problem hiding this comment.
Tu mogłeś skorzystać ze zdefiniowanych readerów
| RSpec.describe Building, type: :model do | ||
| describe 'creating new buildings' do | ||
| before(:each) do | ||
| @clan = create(:clan, id: 1, name: 'Klana') |
There was a problem hiding this comment.
Zdecydowanie ładniej by to wyglądało przy wykorzystaniu let! lub let z wywołaniem w before :)
| describe 'creating new buildings' do | ||
| before(:each) do | ||
| @clan = create(:clan, id: 1, name: 'Klana') | ||
| @building = create(:building, granary: 100) |
There was a problem hiding this comment.
Jako że test dotyczy budynku, do tej zmiennej zamiast wspomnianego wyżej let, można by użyć helpera o nazwie subject do definicji :)
| RSpec.describe Reports::SiegeReport do | ||
| subject(:siege_report) { Reports::SiegeReport.new(building: building).call } | ||
|
|
||
| let(:building) { create(:building, granary: 100) } |
There was a problem hiding this comment.
Można by jeszcze sprawdzić sytuację, gdzie spichlerz nie ma żadnych zasobów :)
/vvvvvvvvvvvv --------------------------------------------------------------
`^^^^^^^^^^^^ /=====================================/
/
katana zamiast opisu. Testy w models nie są częścią zadania. Używałem ich do TDD i zostawiłem.