В одном из наших продуктов в настоящее время мы испытываем некоторые проблемы, связанные с отношением «многие к одному». Ситуация следующая:
Проблема с нашей текущей настройкой заключается в том, что когда мы вставляем новые лайки, каждый лайк получает новый тип лайка с тем же строковым значением, что и другие, в то время как я хочу, чтобы они были с одним и тем же идентификатором.
Более наглядно, это текущая таблица, показывающая наши лайки. У него есть like_type_id, содержащий ссылку на подобный тип.
Это таблица, которую мы имеем для подобных типов. Как видите, он генерирует 2 разных типа лайков с разными id и связывает их с лайками.
Моя предпочтительная ситуация заключается в том, что всякий раз, когда я сохраняю новый лайк, Doctrine проверяет, существует ли уже подобный тип, и если да, связывает уже существующий id типа лайка с подобным. Так что есть только 1 тип лайка «медиа», и оба лайка имеют одинаковый like_type_id.
Вот конфигурация xml моей сущности Like ORM:
<doctrine-mapping xmlns = "http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name = "MyNamespace\Like\Domain\Entity\Like" table = "likes" repository-class = "MyNamespace\Like\Infrastructure\Repository\LikeRepository">
<id name = "id" type = "integer" column = "id" length = "191">
<generator strategy = "AUTO" />
</id>
<field name = "userId" type = "string" length = "191" />
<many-to-one field = "likeType" target-entity = "MyNameSpace\Like\Domain\Entity\LikeType" fetch = "EAGER">
<cascade>
<cascade-persist/>
<cascade-merge/>
</cascade>
</many-to-one>
<field name = "likedObjectId" type = "string" length = "191" />
</entity>
</doctrine-mapping>
А это конфигурация xml подобного типа:
<doctrine-mapping xmlns = "http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name = "MyNameSpace\Like\Domain\Entity\LikeType" repository-class = "MyNameSpace\Like\Infrastructure\Repository\LikeRepository">
<id name = "id" type = "string" length = "191">
<generator strategy = "AUTO" />
</id>
<field name = "type" type = "string" length = "191" />
</entity>
</doctrine-mapping>
Возможно, мы совершаем простую ошибку, но я не смог найти решение этой проблемы, и хотя мы видели некоторые обходные пути, проверяя базу данных на наличие существующего типа лайков, а затем вставляя идентификатор перед сохранением, мы считаем, что это должно быть задача ORM сделать это за нас. Итак, мне интересно, есть ли какие-то ошибки конфигурации, которые мы делаем, чтобы добиться этого.
Заранее спасибо.
-Дэнни Эренс






Сделайте поле like_type.type уникальным, это предотвратит вставку повторяющихся значений:
<field name = "type" type = "string" length = "191" unique = "true" />
И затем, когда вы хотите вставить новый like, вы можете проверить, существует ли уже этот тип:
// This is the name of the like_type --------------------------------------------------------------------v-----------v
if (($LikeType = $entityManager->getRepository('MyNameSpace\Like\Domain\Entity\LikeType')->findOneByName($likeTypeName)) == null)
{
// the Like type wasn't found, create a new one
$LikeType = new LikeType();
$LikeType->setType($likeTypeName);
$entityManager->persist($LikeType);
}
// Whatever if the like type is a new one or not, it can now be set to the like
$Like->SetLikeType($LikeType);
$entityManager->persist($Like);
Спасибо за добавление кода. Итак, в основном это обычная/лучшая практика, чтобы на самом деле делать запросы к базе данных и изменять объект перед его сохранением? Doctrine не предоставляет внутреннего решения, чтобы сделать/отобразить это самостоятельно?
Насколько я знаю, нет, у доктрины нет такой встроенной функции. Для Получить и, если он не существует, создать нет ярлыка
Хорошо. Спасибо, что так быстро ответили. Тогда нет другого способа, чем сделать ваше предложение выше. Спасибо!
Спасибо за быстрый ответ, к сожалению, я пробовал это, и он все еще дает мне тот же результат. Так вот у меня это почему-то не работает. :(