Создание отношения один-к-одному для уже существующей записи с использованием Doctrine ORM (1.2) - PullRequest
3 голосов
/ 27 июля 2011

Справочная информация / Приложение

У меня есть две таблицы базы данных, supplier и address с отношением один к одному, поскольку не все поставщики имеют адрес (и это просто упрощенный пример из более крупного приложения). Я использую Doctrine ORM (1.2) с базой данных MySQL.

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

Следующая схема и четыре простых сценария отображают то, что происходит на каждом этапе процесса.

Схема

Address:
  columns:
    id:
      type: integer
      primary: true
      autoincrement: true
    town: string(300)

Supplier:
  columns:
    id:
      type: integer
      primary: true
      autoincrement: true
    name: string(300)
    address_id: integer
  relations:
    Address:
      foreignType: one

Первый сценарий: создание двух поставщиков с адресом и без него

$supplier = new Supplier();
$supplier->name = 'A supplier with an address';
$supplier->Address->town = 'A town';
$supplier->save();

$supplier = new Supplier();
$supplier->name = 'A supplier without an address';
$supplier->save();

Сценарий второй: подтверждение того, что данные сохранены

$supplier = Doctrine_Core::getTable('Supplier')->find(1);
var_dump($supplier->toArray());

$supplier = Doctrine_Core::getTable('Supplier')->find(2);
var_dump($supplier->toArray());

Выход:

array
  'id' => string '1' (length=1)
  'name' => string 'A supplier with an address' (length=26)
  'address_id' => string '1' (length=1)
array
  'id' => string '2' (length=1)
  'name' => string 'A supplier without an address' (length=29)
  'address_id' => null

Сценарий третий: извлечение и обновление / создание адреса

$supplier = Doctrine_Core::getTable('Supplier')->find(1);
$supplier->Address->town = 'A Different Town';
$supplier->save();
var_dump($supplier->toArray());

$supplier = Doctrine_Core::getTable('Supplier')->find(2);
$supplier->Address->town = 'A New Town';
$supplier->save();
var_dump($supplier->toArray());

Вывод: (Обратите внимание, на этом этапе можно предположить, что адрес был создан для второго поставщика, у которого ранее не было адреса)

array
  'id' => string '1' (length=1)
  'name' => string 'A supplier with an address' (length=26)
  'address_id' => string '1' (length=1)
  'Address' => 
    array
      'id' => string '1' (length=1)
      'town' => string 'A Different Town' (length=16)
array
  'id' => string '2' (length=1)
  'name' => string 'A supplier without an address' (length=29)
  'address_id' => string '2' (length=1)
  'Address' => 
    array
      'id' => string '2' (length=1)
      'town' => string 'A New Town' (length=10)

Сценарий четвертый: подтверждение того, что изменения были сохранены

$supplier = Doctrine_Core::getTable('Supplier')->find(1);
var_dump($supplier->toArray());

$supplier = Doctrine_Core::getTable('Supplier')->find(2);
var_dump($supplier->toArray());

$address = Doctrine_Core::getTable('Address')->find(2);
var_dump($address->toArray());

Выход:

array
  'id' => string '1' (length=1)
  'name' => string 'A supplier with an address' (length=26)
  'address_id' => string '1' (length=1)
array
  'id' => string '2' (length=1)
  'name' => string 'A supplier without an address' (length=29)
  'address_id' => null
array
  'id' => string '2' (length=1)
  'town' => string 'A New Town' (length=10)

Может кто-нибудь объяснить, почему адрес второго поставщика вставляется в базу данных, но на самом деле не связан с поставщиком?

Ответы [ 2 ]

0 голосов
/ 29 июля 2011

Одна вещь, которую я люблю делать при работе с объектами доктрины, особенно в итерации, и если это доставляет мне проблемы, это сбросить объект перед созданием нового.Попробуйте сбросить

unset($supplier)

первый объект, прежде чем назначать $ supplier новый объект доктрины.

0 голосов
/ 28 июля 2011

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

Вам необходимо сохранить изменения адреса перед сохранением поставщика.

В псевдокоде:

 $supplier=Supplier::find(2);

 $supplier->address->name="New town";

 $supplier->adress->save(); //saving de change in database. If you don't do it your change is only in the object

Альтернатива:

 $supplier=Supplier::find(2);

 $address= new Adress();
 $adress->name="New town";
 $adress->save();

 $supplier->adress=$adress;
 $supplier->save();
...