一次管理具有OneToMany关系的多个实体

时间:2012-02-02 22:17:00

标签: php symfony entity

我已经通过实体的关系实现了tanslatable行为,所以我有一个topic实体,其id属性与OneToMany的{​​{1}}关系为topic_id, lang_code和内容。

我可以设置私有$ locale;属性为topic_i18n实体,以使主题的实体__toString()方法显示内容/名称或来自topic实体的任何内容?怎么可能 我完成了吗?

我有另一个疑问,可以扩展到发生topic_i18n关系的任何上下文,就是当我想插入一个我首先需要创建的新OneToMany对象时 目前有一个topic_i18n对象,然后创建i18n对象。我对实体服务层/经理没有经验,但我认为我可以使用范例来管理 两个实体都是一体,但不知道如何进行或者是否是正确的方法。有人可以根据他的经验给出暗示,意见或其他什么吗?

先谢谢!

PD:我知道教条行为捆绑,但现在不可能。

1 个答案:

答案 0 :(得分:3)

我认为你做的方式非常好。

你可以添加/覆盖一些方法来获取你的i18n数据,比如getTitle($ locale)(或get * Whatever *),这会添加一些逻辑,在topic_i18n集合中找到好的值。

// in your Topic class
public function getTitle()
{
    return $this
        ->getTopicI18nCollection()
        ->findByLocale($this->getLocale()) // actually findByLocale does not exist, you will have to find another way, like iterating over all collection
        ->getTitle()
    ;
}

__toString或其他自动化的问题在于区域设置切换,或者如何定义默认使用的默认区域设置。

这可以使用doctrine postLoad事件侦听器来解决,该事件侦听器使用请求或会话信息将当前区域设置设置为EntityManager(http://www.doctrine-project.org/docs/orm/2.1/en/reference/events.html#lifecycle-events)提取的任何实体。

使用symfony2,它看起来像这样:

# app/config/config.yml
services:
    postload.listener:
        class: Translatable\LocaleInitializer
        arguments: [@session]
        tags:
            - { name: doctrine.event_listener, event: postLoad }


// src/Translatable/LocaleInitalizer.php
class LocaleInitializer
{
    public function __construct(Session $session) 
    {
        $this->session = $session;
    }

    public function postLoad(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        if ($entity implements TranslatableInterface) { // or whatever check
            $entity->setLocale($this->session->getLocale());
        }
    }
}

最后,你没有拥有来获取一个主题对象来创建一个新的topic_i18n对象,你可以简单地插入i18n对象。 (但您必须刷新以前提取的集合)。