Используя doctrine, у меня есть две сущности: одна называется Institution, а другая - Location. Каждое учреждение имеет одно местоположение, но два или несколько учреждений могут иметь одно и то же местоположение. Они связаны внешним ключом в Institution.
Учреждение:
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type = "integer")
*/
private $id;
/**
* @ORM\Column(type = "string")
*/
private $name;
/**
* @ORM\ManyToOne(targetEntity = "App\Entity\Location", cascade = {"persist"})
*/
private $location;
Место расположения:
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type = "integer")
*/
private $id;
/**
* @ORM\Column(type = "string", nullable=false)
*/
private $renderedLocation;
/**
*
* @ORM\Column(type = "string", length=60, unique=true, nullable=false)
*/
private $placeId;
Когда добавляется новое учреждение, его спрашивают о местонахождении этого учреждения, которое сохраняет renderedLocation и уникальный placeId с помощью API мест Google. Форма для Location встроена в форму Institution с использованием форм Symfony.
Форма:
$builder
->add('name')
->add('location', LocationType::class)
После отправки формы сохраняется новый Institution и новый Location.
Я хотел бы проверить, возможно ли, что введенное пользователем местоположение уже в базе данных, путем сравнения уникального placeId. В этом случае подключите новый Institution к уже существующему Location. Если нет, создайте новый Institution и новый Location.
Я попытался решить эту проблему с помощью метода, описанного в Предотвращение дублирования в базе данных в отношениях "многие-ко-многим", но безуспешно. Даже если это сработало, использование прослушивателя событий для всех будущих сохранений кажется излишним. Есть идеи, как решить эту проблему?
редактировать: Я сделал то, что предложил М. Халид Джунаид, и проверил дублирование в данных формы. Это работает, но я сомневаюсь, что это правильный способ. Любые предложения приветствуются.
Контроллер:
if ($form->isSubmitted() && $form->isValid()) {
//....
$user->addLinkedInstitution($institution);
$institution = $form->getData();
$placeId = $institution->getLocation()->getPlaceId();
$existingLocation = $em->getRepository('App:Location')->checkDuplicate($placeId)->getQuery()->getOneOrNullResult();
if ($existingLocation != null){
$existingPlaceId = $existingLocation->getPlaceId();
}
else{
$existingPlaceId = null;
}
if ($placeId == $existingPlaceId)
{
$institution->setLocation($existingLocation);
}
Не могли бы вы уточнить? Вы имеете ввиду в контроллере после отправки, но до прошивки? Есть предложения, как это сделать? Спасибо д
Вы пробовали использовать ограничение UniqueEntity для поля placeId?
Я вижу, что вы это уже сделали. Тогда просто получить местоположение с помощью метода поиска репозитория будет достаточно imho. Проверьте, пустой результат или нет.
@ DirkJ.Faber Я имею в виду, когда вы обрабатываете свою форму перед сохранением, просто запрашиваете данные о местоположении из своей базы данных с использованием значений запроса, если уже существуют данные для местоположения, затем назначьте его, иначе создайте его, было бы хорошо, вы можете добавить некоторый связанный код
В чем проблема делать именно то, что вы описываете? Просто проверьте, существует ли местоположение, и подключите учреждение к существующему местоположению перед сохранением ... использование обработчика событий имеет смысл, если вы должны гарантировать, что эта логика всегда происходит с вашей сущностью независимо от форм и контроллера.
@whitelettersinblankpapers, как бы вы это сделали? Потому что, если результат не пустой, вы хотите заменить вставленные данные существующими данными.
@MKhalidJunaid, спасибо за ответ. В моем контроллере это часть обработки моей формы: if ($ form-> isSubmitted () && $ form-> isValid ()) {// ...... // устанавливаем слаг перед сбросом, чтобы логотип имя файла может быть основано на слаге. $ учреждение-> setSlug ($ учреждение-> getInternationalName ()); // сохраняем отправленные данные. $ учреждение = $ форма-> getData (); $ em-> персистировать ($ учреждение); $ em-> flush (); }
@JimPanse, проблема в том, что всякий раз, когда пользователь добавляет новое учреждение, местоположение которого уже существует в базе данных, его нельзя сохранить (благодаря тому, что placeId должен быть уникальным). Если placeId не обязательно должен быть уникальным, местоположение будет дважды сохранено в базе данных, и я получу дубликат.
И еще одна проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда я меняю местоположение учреждения, предыдущее местоположение в таблице Locations изменяется, вместо этого должно быть создано новое местоположение, потому что другие учреждения могут быть связаны с предыдущим местоположением.




Там, где вы сохраняете данные формы, вы можете проверить наличие дубликатов и назначить существующие данные