У меня есть родительский продукт, как можно во многих семьях.
Семейное свойство отображается как CollectionType. Цель состоит в том, чтобы создать столько семейств, сколько мы хотим, но название каждого семейства должно быть уникальным для продукта.
Он отлично работает, когда у меня есть данные в семейной таблице; но когда он пуст и я добавляю сразу два семейства для своего продукта с тем же именем, @UniqueEntity не запускается; в противном случае это ORM uniqueConstraints, как реагировать.
An exception occurred while executing 'INSERT INTO family (name, max_product, required, created_at, updated_at, promotion_id) VALUES (?, ?, ?, ?, ?, ?)' with params ["toto", 1, 0, "2018-12-06 14:54:13", "2018-12-06 14:54:13", 1]:
Ниже образец моих статей:
/**
* @var Family[]|ArrayCollection
*
* @ORM\OneToMany(targetEntity=Family::class, mappedBy = "product", fetch = "LAZY", cascade = {"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"id" = "ASC"})
* @Assert\Valid
*/
private $families;
И
/**
* @ORM\Entity(repositoryClass=ProductCollectionFamilyRepository::class)
* @ORM\Table(name = "product_collection_family",
* indexes = {@ORM\Index(name = "IDX_FAMILY_NAME", columns = {"name"})},
* uniqueConstraints = {
* @ORM\UniqueConstraint(columns = {"promotion_id", "name"})
* }
* )
*
* 2.5.4.5RG02
*
* @UniqueEntity(
* fields = {"product", "name"},
* errorPath = "name",
* message = "backend.error.label.family.unique_entity"
* )
*/
class Family
{
use TimestampableEntity;
use ProductCollectionTrait;
/**
* @var int
*
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type = "integer")
*/
private $id;
/**
* @var string
*
* @ORM\Column(type = "string", length=100)
* @Assert\NotBlank
* @Assert\Length(min = "1", max = "100", minMessage = "backend.error.label.short", maxMessage = "backend.error.label.long")
*/
private $name;
/**
* @var Product
*
* @ORM\ManyToOne(targetEntity=Product::class, inversedBy = "families", fetch = "LAZY")
* @ORM\JoinColumn(name = "product_id", referencedColumnName = "id", nullable=true)
* @Assert\NotBlank
*/
private $product;
}
Любые идеи ?
Но это не ошибка uniqueEntity. Сообщение об ошибке уникального объекта должно иметь вид SQLSTATE [23000]: Нарушение ограничения целостности: 1062 Повторяющаяся запись
@hous Действительно, я забыл часть сообщения, я тоже получил это сообщение: SQLSTATE [23000]: Нарушение ограничения целостности: 1062 Повторяющаяся запись «7-test» для ключа «UNIQ_E346EBFE139DF1945E237E06»
@Robert Проблема возникла, когда я добавлял сразу две или более семьи (это форма CollectionType). Цель состоит в том, чтобы у продукта не было одинакового названия семейства. Когда я добавлял их по одному, все в порядке; но не тогда, когда я пробую все сразу.
тогда вы можете использовать проверку формы, не так ли? :)
@Robert, я попробую с помощью настраиваемого обратного вызова проверки, чтобы проверить дважды в коллекции массивов. Но моей целью было использовать инструменты, предоставляемые фреймворком.






Для этого я просто создаю функцию обратного вызова assert, которая проверяет элементы в коллекции массивов, а затем создаю нарушение.
/**
* @Assert\Callback
*
* @param ExecutionContextInterface $context
* @param $payload
*/
public function validate(ExecutionContextInterface $context, $payload)
{
$productFamilies = clone $this->getProductFamilies();
$productFamiliesFiltered = $this->getProductFamilies()->filter(function ($currentProductFamily) use ($productFamilies) {
// Remove current family from original collection
$productFamilies->removeElement($currentProductFamily);
foreach ($productFamilies as $data) {
//we have same name ?
if ($currentProductFamily->getName() === $data->getName()) {
return true;
}
}
return false;
});
if (0 !== $productCollectionFiltered->count()) {
$context->buildViolation('backend.error.label.product_family.unique_entity')
->atPath('productFamilies')
->addViolation();
}
}
использование UniqueEntity в 2-х полях делает его уникальным, но в двух полях, а не в одном, поэтому, если вы введете продукт A, назовете B, продукт A, имя C, ограничение не сработает. Разве это не твоя проблема?