У меня есть класс сущностей с двумя свойствами: страна и штат. Записи в базе данных должны быть уникальными. Это означает, что если я отправлю в базу данных country=Germany и state=BB, она добавит новую запись, если такой же записи еще не существует.
Однако свойство состояния может быть нулевым, в этом случае оно не отображается доктриной (?), и я все равно могу указать значение для страны. Проблема в том, что я не могу сделать эту запись уникальной, то есть вы не сможете ввести одну и ту же страну несколько раз без уникального состояния. Вот где я борюсь.
Я пробовал различные модификации ограничений сущности.
Вот код, который проверяет, что страна и штат являются уникальной записью в базе данных:
public static function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata->addConstraint(new UniqueEntity([
'fields' => ['country', 'state'],
'message' => 'State is already used with this country!',
]));
}




https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/tutorials/composite-primary-keys.html
Возможно, вам подойдет объект с составным первичным ключом.
/**
* @UniqueEntity
*/
class UniqueEntity
{
/** @Id @Column(type = "string") */
private $country;
/** @Id @Column(type = "string") */
private $state = 'empty'; // case you have no state and a primary key can't be null
public function __construct($country, $state)
{
$this->country= $country;
$this->state= $state;
}
public function getCountry()
{
return $this->country;
}
public function getState()
{
return $this->state;
}
}
Единственное ограничение заключается в том, что вы не можете иметь нулевое значение в качестве состояния, если это первичный ключ. Но опять же, вы можете иметь значение по умолчанию, например «нет», в качестве значения состояния, которое будет как приемлемым ключом, так и уникальным стоимость
Спасибо за ответ; возможно, мой вопрос был немного неясным, но и страна, и штат являются частью одного и того же объекта.
Понятно, что составной ключ — это уникальный ключ, состоящий из 2 или более полей вашего объекта, в вашем штате и стране, что гарантирует уникальность комбинации обоих. Единственное ограничение заключается в том, что вы не можете иметь нулевое значение в качестве состояния, если это первичный ключ. Но опять же, вы можете иметь значение по умолчанию, например «нет», в качестве значения состояния, которое будет как приемлемым ключом, так и уникальным стоимость
Я знаю, что это составной ключ, но в этом объекте есть только один ключ, и я не собираюсь создавать фиктивные данные для генерации первичного ключа. :/
Мне потребовалось некоторое время, но это собственный класс валидатора, который я написал для решения своей проблемы. Может быть, это поможет кому-то еще.
<?php
namespace XXX;
use XXX\Services\CountryAndStateService;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class CountryAndStateValidator extends ConstraintValidator
{
/**
* @var countryAndStateService
*/
private $countryAndStateService;
/**
* CountryAndState constructor.
*/
public function __construct(CountryAndStateService $countryAndStateService)
{
$this->countryAndStateService = $countryAndStateService;
}
/**
* Taking country and state; validating whether the same country with state === null does already exist.
*
*/
public function validate($value, Constraint $constraint)
{
/* Accessing user input of state and country */
$state = $this->context->getRoot()->getData()->getState();
$country = $this->context->getRoot()->getData()->getCountry();
/* Comparing the country user input to the country data in the database */
$existingCountry = $this->countryAndStateService->getCountryByCountry($country);
if ($state === null) {
if ($existingCountry) {
$this->context->buildViolation($constraint->message)
->addViolation();
} else {
return;
}
}else {
return;
}
}
}
Я думаю, вам нужно будет написать собственное ограничение, как описано здесь: symfony.com/doc/current/validation/custom_constraint.html