Symfony 2 - 根据另一个表中新插入的记录更新表

时间:2012-07-07 18:18:52

标签: symfony doctrine-orm

我正在尝试使用Symfony 2和Doctrine 2创建一个小型论坛应用程序。我的ForumTopic实体有一个last_post字段(oneToOne映射)。现在当我用

坚持我的新帖子时
$em->persist($post);

我想更新我的ForumTopic实体,以使其last_post字段引用此新帖子。我刚刚意识到使用Doctrine postPersist Listener无法做到这一点,所以我决定使用一个小黑客,然后尝试:

$em->persist($post);
$em->flush();
$topic->setLastPost($post);
$em->persist($post);
$em->flush();

但它似乎没有更新我的主题表。

我还看了http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/reference/working-with-associations.html#transitive-persistence-cascade-operations希望它能解决问题,方法是将cascade:['persist']添加到我的Topic.orm.yml文件中,但它也无济于事。

有人能指出我的解决方案或示例类吗?

我的论坛是:

FrontBundle\Entity\ForumTopic:
        type: entity
        table: forum_topics
        id:
                id:
                        type: integer
                        generator:
                                strategy: AUTO
        fields:
                title:
                        type: string(100)
                        nullable: false
                slug:
                        type: string(100)
                        nullable: false
                created_at:
                        type: datetime
                        nullable: false
                updated_at:
                        type: datetime
                        nullable: true
                update_reason:
                        type: text
                        nullable: true
        oneToMany:
                posts:
                        targetEntity: ForumPost
                        mappedBy: topic
        manyToOne:
                created_by:
                        targetEntity: User
                        inversedBy: articles
                        nullable: false
                updated_by:
                        targetEntity: User
                        nullable: true
                        default: null
                topic_group:
                        targetEntity: ForumTopicGroup
                        inversedBy: topics
                        nullable: false
        oneToOne:
                last_post:
                        targetEntity: ForumPost
                        nullable: true
                        default: null
                        cascade: [ persist ]
        uniqueConstraint:
                uniqueSlugByGroup:
                        columns: [ topic_group, slug ]

我的ForumPost是:

FrontBundle\Entity\ForumPost:
        type: entity
        table: forum_posts
        id:
                id:
                        type: integer
                        generator:
                                strategy: AUTO
        fields:
                created_at:
                        type: datetime
                        nullable: false
                updated_at:
                        type: datetime
                        nullable: true
                update_reason:
                        type: string
                        nullable: true
                text:
                        type: text
                        nullable: false
        manyToOne:
                created_by:
                        targetEntity: User
                        inversedBy: forum_posts
                        nullable: false
                updated_by:
                        targetEntity: User
                        nullable: true
                        default: null
               topic:
                        targetEntity: ForumTopic
                        inversedBy: posts

1 个答案:

答案 0 :(得分:0)

我相信你让自己变得更加困难,因为你认为你必须先刷新你的帖子,然后再将它设置为关于你主题的关联。

Doctrine非常聪明,如果你坚持一个实体并将其设置为一个关联而没有先调用flush,它会确保当你调用flush时,它会先保留该实体,这样它就有一个ID可以与协会一起使用。

这意味着您真正需要做的就是:

// Assume that topic has been fetched from the DB, and post is completely new
$topic = $em->find('TopicModel', $topicId);
$post = new ForumPost();
// Fill in the post info
// Set up the association
$topic->setLastPost($post);
// And finally, persist and flush - no more effort needed
$em->persist($post);
$em->flush();

这样做的好处是你可以简单地使用prePersist事件监听器来更新帖子的最后一篇文章 - Doctrine将为你处理其他一切。

或者,如果你想要一种逻辑上更容易理解的方法,你可以自己让Post模型调用setLastPost - 例如,如果你在构造函数或setTopic中设置post的主题( )方法,在那里添加setLastPost调用。

让一个协会的一方照顾这样的双方是相对常见的做法,以帮助保持良好的同步 - 见Working with Associations