Я пытаюсь обновить объект отношения "один-два-один" объекта.
Это код, который я использую:
$em = $this->getDoctrine()->getManager();
$request = Request::createFromGlobals();
$user = $this->get('security.context')->getToken()->getUser();
# find thread
$thread = $em->getRepository('MyBundle:Thread')->findThreadById($threadid);
# find thread posts
$query = $em->getRepository('MyBundle:Post')->findThreadPosts($thread->getId());
# create form
$form = $this->createForm(new PostType(), new Post($user, $thread));
# handle form
$form->handleRequest($request);
if ($form->isValid()) {
$post = $form->getData();
$em->persist($post);
$em->flush();
$logger->debug("POST CREATED with id: " . $post->getId());
$thread->setLastPost($post);
$thread->addPostCount(1);
$thread->setLastPostCreator($user);
$em->flush();
$logger->debug("ADDED LAST POST TO thread with id: " . $thread->getId());
$forum = $thread->getForum();
$forum->setLastPostCreator($user);
$forum->addPostCount(1);
$forum->setLastPostCreator($user);
$forum->setLastPost($post);
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
'Your post has been added!'
);
}
$data['posts'] = $posts;
$data['thread'] = $thread;
$data['form'] = $form->createView();
Отображение сообщения:
<?xml version="1.0" encoding="utf-8"?>
<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 http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="MyBundle\Entity\Post" table="post">
<id name="id" type="integer" column="id">
<generator strategy="IDENTITY"/>
</id>
<field name="text" type="text" column="text" nullable="false"/>
<many-to-one field="thread" target-entity="Thread" inversed-by="posts">
<join-columns>
<join-column name="thread_id" referenced-column-name="id"/>
</join-columns>
</many-to-one>
</entity>
</doctrine-mapping>
Отображение темы:
<?xml version="1.0" encoding="utf-8"?>
<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 http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="MyBundle\Entity\Thread" table="thread">
<id name="id" type="integer" column="id">
<generator strategy="IDENTITY"/>
</id>
<field name="postCount" type="integer" column="post_count" nullable="false"/>
<one-to-one field="lastPost" target-entity="Post">
<join-column name="last_post_id" referenced-column-name="id"/>
</one-to-one>
<one-to-many field="posts" target-entity="Post" mapped-by="thread" />
</entity>
</doctrine-mapping>
Объект: установщик потоков
public function setLastPost(Post $lastPost)
{
$this->lastPost = $lastPost;
}
public function getLastPost()
{
return $this->lastPost;
}
Поэтому всякий раз, когда я добавляю сообщение, я обновляю его родительский (поток). Таким образом, поток имеет последнее сообщение в виде ссылки "много-в-один". Я также обновляю счет только как вопрос кэширования и сокращения объединений.
счет действительно увеличивается правильно. Однако последнее сообщение не обновляется. Когда я просматриваю свои журналы отладки, я также вижу, что для этого не выполняется запрос.
любые идеи/мысли по этому поводу? моя лучшая догадка заключалась в том, что он не обнаружил изменений, но я понятия не имею, как сделать недействительными такие данные.
Я думаю, проблема в том, что вы настраиваете и сохраняете "обратную сторону" отношений. Документы говорят:
Доктрина будет проверять только принадлежность ассоциации к изменениям.
а также
ManyToOne всегда является владением двунаправленной ассоциацией.
Таким образом, в вашем случае у вас есть многоточечное двунаправленное отношение между потоком и lastPosts, где объект lastPost является "стороной-обладателем" (многосторонняя сторона), а поток - "обратная сторона". Я считаю, что у вас должна быть функция setThread() для вашего объекта Post, и если после обработки формы вы запускаете $post-> setThread ($ thread), а затем сохраняете ($ post), все будет работать.
Кроме того, IMO, похоже, что вы должны иметь отношения между thread-> сообщениями и использовать пользовательскую функцию репозитория, или находить и сортировать по дате createdAt (при условии, что она существует) для получения "последнего сообщения". Мне кажется, что отношения "Много нитей к одному последнему сообщению" мне кажутся неправильными, не должны ли нить иметь только один "последний пост" (aka oneToOne)?
Я просто столкнулся с этим. Решение, которое сработало для меня, состояло в вызове $em->merge($entity);
на каждом из объектов на стороне "много", а затем $em->flush();
,
ваш метод $thread-> setLastPost ($ post) выглядит следующим образом:
public function setLastPost(Post $post)
{
$this->lastPost = $post;
}
Вызывается? Что происходит при вставке отладочной инструкции?
Правильно ли вы установили право на право, если это необходимо?
"So, all that by_reference=false really does is force the framework to call the setter on the parent object."
http://symfony.com/doc/current/reference/forms/types/collection.html#by-reference
Если вышеприведенные рекомендации не работают, не могли бы вы предоставить дополнительную информацию, такую как FormTypes и соответствующие сущностные сеттеры и геттеры?!