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


Managing multiple entities, with OneToMany relationships, at once

>我已经通过实体的关系实现了 tanslatable 行为,所以我有一个带有 id 属性的topic实体,该属性与topic_id topic_i18n关系OneToMany,lang_code和内容。

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

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

提前感谢!

PD:I了解教义行为捆绑,但现在是不可能的。

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

您可以添加/覆盖一些方法来获取 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或其他功能的自动化问题在于区域设置切换,或者如何定义默认使用的默认区域设置。

这可以使用原则 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 对象。(但您必须刷新以前获取的集合(。