Как объединить две доктрины в одном объекте - PullRequest
0 голосов
/ 02 июля 2010

В моей базе данных управление пользователями разделено на две таблицы: - Один создан плагином symfony sfDoctrineGuard (sfGuardUser), с именем пользователя, паролем и другой информацией, используемой плагином - еще один, который я создал, чтобы расширить эту таблицу с помощью дополнительных свойств, таких как имя, фамилия и т. д. *

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

С этой целью я сделал соединение двух таблиц следующим образом:

$q = $this->createQuery()
->from('sfGuardUser u')
->leftJoin('u.Mishmember m WITH u.id = ?', $rel['member_id']);

$member = $q->fetchOne();

Моя проблема в том, что сгенерированный запрос кажется правильным, поскольку он выбирает все атрибуты обеих таблиц, но в переменной $ member я могу получить доступ только к свойствам объекта sfGuardUser.

Я хочу, чтобы объект $ member инкапсулировал все свойства обеих таблиц / объектов доктрины.

Как бы вы это сделали?


EDIT1: если я сделаю

print_r($member->toArray()) 

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

Array (
   [table1-prop1] => value 
   [table1-prop2] => value 
   [table1-prop3] => value 
   [Table2] => Array (
                  [table2-prop1] => value 
                  [table2-prop2] => value 
                  [table2-prop3] => value 
                  [table2-prop4] => value
   )
) 

Итак, чтобы получить доступ к свойству table2-prop3, я должен сделать: $ Var [Table2] [table2-prop3];

Это не то, что я хочу, потому что я хочу рассматривать все свойства как часть как тот же объект или массив (как если бы была только одна таблица.)

Если вы все еще со мной, приведенный выше массив должен выглядеть так:

Array (
   [table1-prop1] => value 
   [table1-prop2] => value 
   [table1-prop3] => value 
   [table2-prop1] => value 
   [table2-prop2] => value 
   [table2-prop3] => value 
   [table2-prop4] => value
   )
) 

Надеюсь, это поможет понять мою проблему.


EDIT2 (ответ на DuoSRX и DrColossos)

Спасибо вам обоим за интересные ответы.

Ну, причина, по которой я бы предпочел не иметь свойства Mishmember в моем sfGuardUser, заключается в том, что обе таблицы / классы обозначают одну и ту же сущность (пользователя). Хотя эта фрагментация неизбежна в моей базе данных (было бы неразумно редактировать непосредственно sfGuardPlugin для добавления моих свойств), я бы хотел, чтобы код приложения был таким, как если бы у меня была одна таблица, потому что это было бы много более разумным и логичным в использовании (представьте, что другому разработчику, который не знает модель, придется работать над контроллером или шаблонами ...)

Что бы вы подумали о добавлении класса Doctrine User, который наследуется от sfGuardUser и Mishmember (есть ли множественное наследование в PHP5?), Чтобы у моего контроллера был только один класс пользователя для работы?

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

Я не уверен, как работает наследование доктрин, но мне кажется, что это самое лучшее решение (скажите, пожалуйста, если я ошибаюсь!)

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

Ответы [ 2 ]

1 голос
/ 02 июля 2010

Если вам не нужны объекты, а только массивы, вы можете сделать:

$result = $query->fetchArray();
$mishmember = $result['Mishmember'];
unset($result['Mishmember']);
$user = array_merge($result, $mishmember);

Это должно сработать, но я думаю, что это слишком сложно.В чем проблема с наличием многомерного массива?

Редактировать:

Ну тогда вы можете использовать простое наследование или наследование column_aggregation:

Mishmember:
  inheritance:
    type: simple (or column_aggregation)
    extends: sfGuardUser
  columns:
    myfield: 
      type:integer

И затем:

$mishmember = Doctrine::getTable('Mishmember')->find(1);
echo $mishmember->myfield;

Подробнее о наследовании см. В документации по доктрине .

0 голосов
/ 02 июля 2010

Это не совсем то, как работают ORM: как вы заметили, вы получаете sfGuardUser Object / Array обратно. Теперь Mishmember - это не что иное, как свойство для sfGuardUser (это совпадение, то есть сам объект). Так что вместо того, чтобы иметь, например, строковое свойство, у вас есть свойство объекта / массива.

edit: С вашей стороны вы можете объединить / объединить / воссоздать массив / объект (как предлагает другой ответ), если вам не нравится многомерный аспект. Но имейте в виду, что эти операции могут быть довольно сложными, когда у вас есть большие объемы возвращаемых данных.

...