2016-06-13 2 views
0

У меня есть две таблицы в моей настройке sonata-admin с Symfony2: 'product' и 'product_description'. Второй содержит описания продуктов на нескольких языках и определяет столбцы product_id и language_id как составной первичный ключ. В таблице продуктов нет столбца language_id, чтобы он динамически соединялся с описанием в зависимости от языка, который выбрал клиент.JoinColumns on column и static value

В настоящее время я пытаюсь присоединиться к их помощи OneToOne и JoinColumns аннотацию, однако, как можно product_description соединить с language_id как статическое значение (которое не присутствует в виде столбца в таблице продукта)?

/** 
* ProductDescription 
* 
* @ORM\Table(name="product_description") 
* @ORM\Entity 
*/ 
class ProductDescription 
{ 

/** 
* @var integer 
* 
* @ORM\Column(name="product_id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="NONE") 
*/ 
private $productId; 

/* 
* @var boolean 
* 
* @ORM\Column(name="language_id", type="boolean") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="NONE") 
*/ 
private $languageId; 

.... 

} 



/** 
* Product 
* 
* @ORM\Table(name="product") 
* @ORM\Entity 
*/ 
class Product 
{ 

/** 
* @var integer 
* 
* @ORM\Column(name="product_id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="NONE") 
*/ 
private $productId; 

/** 
* @ORM\OneToOne(targetEntity="ProductDescription") 
* @ORM\JoinColumns({ 
*  @JoinColumn(name="product_id", referencedColumnName="product_id"), 
*  @JoinColumn(name="??????", referencedColumnName="language_id") 
* }) 
*/ 
private $productDescription; 

.... 

} 

редактировать: больше кода добавлен

// admin class 
protected function configureListFields(ListMapper $listMapper) 
{  
    $listMapper->addIdentifier('productId', 'integer') 
     ->addIdentifier('productDescription.productName'); 
} 

protected function configureFormFields(FormMapper $formMapper) 
{ 
    $formMapper->add('offersId', 'integer', array('read_only' => true)) 
     ->add('productDescription.productName'); 
} 

Я пытался присоединиться к нему вручную с QueryBuilder в CreateQuery() метод, однако даст непредсказуемый результат в виде списка.

public function createQuery($context = 'list') 
{ 
    $query = parent::createQuery($context); 

    $query->addSelect('p')->innerJoin('AppBundle\Entity\ProductDescription', 'p', 'WITH', $query->getRootAlias().'.productId = p.productId and p.languageId = 2'); 

    return $query; 
} 

Редактировать: Вот аналогичный вопрос в Hibernate - возможно, переносимый доктриной?

https://forum.hibernate.org/viewtopic.php?f=1&t=986966

+0

У вас есть код, чтобы показать нам? –

+0

Код добавлен, как присоединиться к этим двум таблицам на product_id и статическому значению для language_id, скажем 2. – Chris

ответ

0

Насколько я понял, нет «язык» существует в вашей модели, так что вы не можете создать отношения к любому. Что вы можете сделать, это просто создать строки или целый столбец типа и просто держать свое значение языка в нем:

/** 
    * @ORM\Column(type="string") 
    * @var string 
    */ 
private $languageId 

Вы можете использовать сеанс языковой или есть некоторая константа в модели с некоторой проверкой действительного ID:

const LANGUAGE_ID_EN = 'en'; 
const LANGUAGE_ID_FR = 'fr'; 

public function setLanguageId($languageId) 
{ 
    if (! in_array($$languageId, [...]) { 
     throw new \Exception(...); 
    } 

    $this->languageId = $languageId; 
} 

Тогда вам просто делать запросы с дополнительным ИНЕКЕ:

WHERE language_id = ? 

Я надеюсь, что у меня есть ты прав. Сообщите нам, если ваша цель - это нечто иное.

+0

Да, вы поняли меня правильно, однако я использую sonata-admin, который не дает возможности объявить собственный оператор SQL. Поэтому я ищу решение только с аннотацией JoinColumns. – Chris

+0

Укажите, что вы собираетесь использовать. Какой контроллер/метод/случай вам нужен именно так? Тогда было бы легче подумать о решении. Sonata Admin, так как многие другие компоненты или компоненты «хорошей архитектуры» позволяют вводить пользовательские вещи, нам просто нужно понять, где именно это сделать, поскольку методы могут отличаться. PS. И Join - это модельное отношение, поэтому НЕ МОЖЕТ БЫТЬ такое решение. Узнайте больше о базах данных и Доктрине, чтобы понять невозможность вашей воли. ;) – lllypa

+0

Я очень в базах данных, но symfony, а также доктрина для меня совершенно новые;) Я просто не понимаю, почему нет возможности использовать только статическое значение в аннотации JoinColumn. В чем причина постоянного предоставления существующего столбца в обоих объектах базы данных? Для моего случая использования это не очень удобно! И как вы, кажется, поняли мою проблему, не могли бы вы привести только пример того, как этот сценарий будет обрабатываться в среде sonata-admin? Мне просто нужен образец, как это сделать, нет необходимости адаптировать все к моим контроллерам/методам и т. Д. – Chris