Отображение двух таблиц на одну сущность в Doctrine2 - PullRequest
2 голосов
/ 21 апреля 2011

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

Iу меня есть много таблиц, в которых есть таблицы партнеров, в которых хранятся данные перевода, подобные следующим ....

Tables ER diagram

Где бы я хотел иметь один объект (элемент навигации), который имел доступ кПоле 'label' в зависимости от того, какой язык я установил в своем приложении.Из документации Doctrine следует, что вам нужно определить одну (одну) таблицу, которая используется для сохранения сущности

http://www.doctrine -project.org / docs / orm /2.0 / en / reference / basic-mapping.html По умолчанию сущность будет сохранена в таблице с тем же именем, что и имя класса.Чтобы изменить это, вы можете использовать аннотацию @Table следующим образом:

Или мне нужно определить две сущности и связать их (или позволить таблице перевода наследоваться от таблицы элементов).

И какую стратегию я бы использовал, чтобы всегда вставлять предложение language_id в Join (чтобы убедиться, что я вытягиваю правильную метку для текущего установленного языка).Это то, что я определил бы в самой сущности или где-то еще?

Ответы [ 2 ]

2 голосов
/ 21 апреля 2011

Это похоже на двунаправленную ассоциацию «один ко многим» . Вот сценарий с этой страницы, переведенный в вашу ситуацию:

/** @Entity */
class NavigationElement
{
    // ...
    /**
     * @OneToMany(targetEntity="NavigationElementTranslation", mappedBy="navigationElement")
     */
    private $translations;
    // ...

    public function __construct() {
        $this->translations = new \Doctrine\Common\Collections\ArrayCollection();
    }
}

/** @Entity */
class NavigationElementTranslation
{
    // ...
    /**
     * @ManyToOne(targetEntity="NavigationElement", inversedBy="translations")
     * @JoinColumn(name="navigation_element_id", referencedColumnName="id")
     */
    private $navigationElement;
    // ...
}

Вы можете добавить метод getLabel($languageId) к объекту NavigationElement, который просматривает переводы, чтобы получить правильную метку:

public function getLabel($languageId) {

    foreach($this->translations as $trans) {
        if($trans->languageId == $languageId)
            return $trans->label;
    }

    throw new InvalidArgumentException();
}

И вы можете использовать следующий DQL, чтобы убедиться, что вы загружаете только нужный перевод в свойство $translations:

$query = $em->createQuery(
    "SELECT ne, net
     FROM Entity\NavigationElement ne
     JOIN ne.translations net WITH net.languageId = :langId"
);
$query->setParameter('langId', $languageId);
$navigationElements = $query->execute();

Эта ситуация звучит так, как будто вы хотите агрессивно кэшировать. Обязательно изучите механизмы кэширования Doctrine 2 .

Кроме того, интернационализация может быть достаточно хорошо обработана в PHP с помощью gettext , если вы обнаружите, что таблицы соединений для переводов начинают становиться неуправляемыми.

0 голосов
/ 27 апреля 2011

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

http://www.gediminasm.org/article/translatable-behavior-extension-for-doctrine-2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...