У меня есть два класса сущностей:
class A {
/**
* @Assert\LessThanOrEqual(3)
*
* @var int
*/
protected $attempts;
}
class B extends A {
/**
* @Assert\LessThanOrEqual(5)
*
* @var int
*/
protected $attempts;
}
И 1 тест для проверки правильности работы валидации:
public function testSetAttemptsCount()
{
$block = new B();
$block->setAttempts(6);
$errors = $this->getService('validator')->validate($block);
$this->assertHasViolation($errors, 'attempts', LessThanOrEqual::TOO_HIGH_ERROR);
$block->setAttempts(4);
$errors = $this->getService('validator')->validate($block);
$this->assertNotHasViolation($errors, 'attempts', LessThanOrEqual::TOO_HIGH_ERROR);
}
Этот тест не пройдет, потому что он проверяет значение assert из класса A. Кто-нибудь знает, как я могу «переписать» правило проверки для поля?
Действительно, очень интересно ... Я могу подтвердить, что это текущее поведение в v4.1, и, копаясь в документации, чтобы найти ключ, я обнаружил проблему на GitHub (github.com/symfony/symfony/issues/15582) и фиксации Фабьена (github.com/symfony/symfony/pull/21053), которая указывает на это направление. Похоже, что это было исправлено в 2.7, но вскоре было восстановлено из-за поломки BC ... :(
Действительно интересно. Один из способов сделать это - сделать класс C из класса A и создать абстрактный класс A, расширенный B и C. Однако это не дает ответа на вопрос.
Извините, неправильная ссылка на проблему. Правильный: github.com/symfony/symfony/issues/15950






На данный момент я собираюсь завершить свой поиск решения. Понятно, что была попытка решить эту проблему, но это привело к какой-то поломке BC, однако я не нашел никаких упоминаний об этом (чтобы мы могли лучше это понять). В конце концов, основные версии допускают разрывы BC, и, на мой взгляд, либо 3.0, либо 4.0 были хорошими кандидатами для этого, но как-то проскользнули в мысль.
Лучшее, что у меня есть (но не достаточное и ни в коем случае не идеальное), - это цитата из документы:
This means you are able to add new constraints to a property, but you cannot override them ... To create your own validation, add the constraints to a new validation group
Действительно, определение собственных групп проверки может быть потенциальным решением этой проблемы, но мы вернемся к исходной точке, если у нас нет контроля над родительскими классами (а мы обычно этого не делаем). Таким образом, это потребует переопределения всех свойств базового класса в нашем дочернем классе. Это действительно превосходит цель.
Полученное выше, может быть применено несколько менее забавное решение, если мы перенесем наши правила проверки на YAML или XML. Итак, никаких аннотаций. В YAML это выглядело бы примерно так:
App\Data\Foo:
properties:
attempts:
- LessThanOrEqual: 2
another:
- LessThanOrEqual: 5
App\Data\Bar:
properties:
attempts:
- LessThanOrEqual: {value: 5, groups: [Overriden]}
another:
- LessThanOrEqual: {value: 5, groups: [Overriden]}
В приведенном выше примере конфигурации мы можем скопировать и вставить существующие правила проверки, вставить собственный Bar extends Foo (в моем случае group) и использовать его. Таким образом, мы проверяем те ограничения, исходящие от родительского класса, которые нас интересуют, и включаем наши собственные из дочернего класса. Немного больше усилий потребуется, если родительский класс использует другой формат правила проверки ...
Я очень хочу посмотреть, сможет ли кто-нибудь придумать лучший подход, поскольку я считаю, что это действительно должно сработать в наших условиях ...
Надеюсь это немного поможет...
Интересно ... Можно сказать, так и должно работать. Буду следить за этим.