2014-11-16 3 views
0

Im пытается обновить объект отношения «один-два-один» объекта.Отношение доктрины Doctrine не обновляется

Это код, я использую:

$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(); 

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\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> 

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> 

Entity: сеттер Тема

public function setLastPost(Post $lastPost) 
{ 
    $this->lastPost = $lastPost; 
} 

public function getLastPost() 
{ 
    return $this->lastPost; 
} 

Поэтому всякий раз, когда я добавляю сообщение, я обновляю его родительский (поток). Таким образом, поток имеет последнее сообщение в виде ссылки «много-в-один». Я также обновляю счет только как вопрос кэширования и сокращения объединений.

счет действительно увеличивается правильно. Однако последнее сообщение не обновляется. Когда я просматриваю свои журналы отладки, я также вижу, что для этого не выполняется запрос.

любые идеи/мысли по этому вопросу? моя лучшая догадка заключалась в том, что она не обнаруживает изменения, но я понятия не имею, как сделать недействительными данные такого типа.

+0

Нам нужно увидеть сопоставления для сообщений и потоков. –

+0

Обновлено мое исходное сообщение с сопоставлениями –

+0

Неужели 'Thread :: lastPost' установлен никогда? Или он не может быть изменен после первого раза, когда установлена ​​ассоциация? Можете ли вы добавить действие с созданием «Thread»? – origaminal

ответ

2

Я думаю, проблема в том, что вы настраиваете и сохраняете «обратную сторону» отношений. Документы говорят:

Doctrine проверит только принадлежность ассоциации к изменениям.

и

ManyToOne всегда владеющая сторона двунаправленной ассоциации.

Так что в вашем случае, у вас есть ManyToOne двунаправленную связь между потоком и lastPosts, где компания lastPost является «владеющим сторона» (сторона ManyToOne) и нить есть «обратная сторона». Я считаю, что у вас должна быть функция setThread() для вашего объекта Post, и если после обработки формы вы запускаете $ post-> setThread ($ thread), а затем сохраняете ($ post), все будет работать.

Кроме того, IMO, похоже, что вы должны просто иметь отношения между thread-> сообщениями и использовать пользовательскую функцию репозитория или находить и сортировать по дате createdAt (при условии, что она существует) для получения «последнего сообщения», , Мне кажется, что отношения «Много нитей к одному последнему сообщению» мне кажутся неправильными, не должны ли нить иметь только один «последний пост» (aka oneToOne)?

+0

Последнее сообщение - это тяжелый запрос, его также часто обновляют на занятом форуме. вот почему я решил иметь поле кэширования (которое обычно никогда не используется в СУБД). Пожалуйста, исправьте меня, если я ошибаюсь. Сейчас я тестирую ваше решение. –

+0

Да, это правильно, он должен быть взаимно однозначным. теперь корректируется и будет обновляться, если работает как можно скорее. –

+0

Это имеет смысл. Я добавил примечание о связи thread-> lastPost. Если это отношения oneToOne, я думаю, что способ настройки вашего контроллера будет работать, потому что документы говорят, что в oneToOne сторона с внешним ключом является стороной-владельцем (поток в вашем случае). –

0

делает ваш $ резьбовых> setLastPost метод ($ пост) выглядит следующим образом:

public function setLastPost(Post $post) 
{ 
    $this->lastPost = $post; 
} 

ли дозвонились? Что происходит при вставке отладочной инструкции?

Вы установили by_reference правильно, если это необходимо?

"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 и соответствующих инкубационных сущностей и добытчиками ?!

+0

Здравствуйте, благодарю вас за ответ. Вызывается функция setLastPost и выглядит как установщик, который вы опубликовали. by_reference не требуется, так как я получаю поток. Я обновил свой оригинальный пост с более подробным кодом. Я не думаю, что FormTypes актуальны в этом случае. Я также добавил свои сущности –

+0

Что происходит, когда вы это делаете: public function setLastPost (Post $ post) { $ this-> lastPost = $ post; $ post-> setThread ($ this); } – PaulSchell

+0

Ничего не меняет, сообщение уже имеет связь с нитью. как определено здесь: 'new Post ($ user, $ thread)' –

Смежные вопросы