Это похоже на двунаправленную ассоциацию «один ко многим» . Вот сценарий с этой страницы, переведенный в вашу ситуацию:
/** @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 , если вы обнаружите, что таблицы соединений для переводов начинают становиться неуправляемыми.