Vote count:
0
I'm refining a Rails 4 high scores API that I built. The change I want to make is to reject bad scores for a specific game.
Game has_many scores
Score belongs_to Game
The way I've been trying to do this based on the official docs is to use with_options :if:
# Asteroids validations
with_options :if => :is_asteroids? do |score|
score.validate :elapsed_and_lives_included?
score.validate :asteroids_elapsed_and_lives_valid?
score.validates :player,
length: { in: 1..10 },
allow_blank: false
score.validates :value,
numericality: {
greater_than_or_equal_to: 0,
}
score.validates :level,
numericality: {
greater_than: 0,
less_than_or_equal_to: 50
}
end
def is_asteroids?
game_id == 2 && is_seed.nil?
end
def elapsed_and_lives_included?
if @elapsed.nil? || @lives.nil?
errors[:base] << "Must include elapsed time and lives"
return false
end
true
end
def asteroids_elapsed_and_lives_valid?
if @lives > 0 && self.level != 50 || @lives > @elapsed
errors[:base] << "Invalid number of lives"
return false
elsif @elapsed < self.level * 300
errors[:base] << "Invalid elapsed time"
return false
end
true
end
But I've run into some pretty serious problems with this.
First, using score.validate/validates in the with_options block causes the validations in the block to not run at all, resulting in the Score instance I pass in through the Rails console to be considered valid even when the validation conditions are not met.
Removing score. from each validation in the block seems to solve that problem, but another issue I've run into is that the method called by the :if statement on which the validations in the block are based never seems to be evaluated for any of the validations in the block - whether score. is used or not. This means that the validations in the block, which are meant specifically for scores coming from Asteroids, will run for scores not coming from Asteroids.
That is, when I pass a Score in with game_id != 2, each of the validations in with_options is run when score. is removed; but if I add score., the validations don't run period, causing the invalid object to be seen by Rails as valid.
I'm caught between a rock and a hard place. What am I screwing up here?
Aucun commentaire:
Enregistrer un commentaire