Есть несколько способов сделать это, но все они включают переписывание grab_colors для выполнения проверки validates_presence_of.
Вы настраиваете обратный вызов before_validation. Любой обратный вызов, который возвращает false, отменяет оставшуюся часть транзакции. Поэтому вам нужно разобраться с этим случаем, который заставляет grab_colors работать самостоятельно. По сути, вы просите что-то вроде этого:
def grab_colors
unless size.blank?
# grab x number of colors | x = size
else
errors.add(:size, "cannot be empty.")
return false
end
end
Это объединяет ваш пользовательский before_validation с validates_presence_of. Если размер не существует, grab_colors установит ошибку и вернет false, отменяя оставшуюся часть транзакции, поэтому ваши стандартные проверки никогда не будут выполнены. Из того, что вы упомянули, единственный раз, когда это терпит неудачу, это когда размер не установлен.
Вы также можете достичь желаемого эффекта, если бы number_of_colors вызывал grab_colors вместо вызова grab_colors в качестве before_validation. Тем не менее, вам все равно придется настроить grab_colors для обработки ошибки, когда размер не определен.