Background / Application
I have two database tables, supplier
and address
with a one-to-one relationship, as not all suppliers have an address (and this is just a simplified example from a larger application). I'm using the Doctrine ORM (1.2) with a MySQL database.
I am having troubles with adding an address to a pre-existing supplier who doesn't have one. I can modify the address of a pre-existing supplier who does have one without issue.
The following schema and four simple scripts display what is开发者_JAVA百科 happening at each stage of the process.
Schema
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
Script One: Create two suppliers, with and without an address
$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();
Script Two: Confirm data has been saved
$supplier = Doctrine_Core::getTable('Supplier')->find(1);
var_dump($supplier->toArray());
$supplier = Doctrine_Core::getTable('Supplier')->find(2);
var_dump($supplier->toArray());
Output:
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
Script Three: Fetch and update / create an address
$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());
Output: (Note, at this point, it would suggest that the address was created for the second supplier who previously didn't have an address)
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)
Script Four: Confirm that the changes were saved
$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());
Output:
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)
Can anyone explain why the address for the second supplier is being inserted into the database but not actually being linked to the supplier?
I don't know Doctrine. I Use Propel, but I think that if you save the supplier you are not saving the address in database.
You need to save the changes in address before you save the supplier.
In pseudocode:
$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
An alternative:
$supplier=Supplier::find(2);
$address= new Adress();
$adress->name="New town";
$adress->save();
$supplier->adress=$adress;
$supplier->save();
One thing I like to do when working with doctrine objects, especially in an iteration, and if it is giving me problems is to unset the object before creating a new one. Try unsetting
unset($supplier)
the first object before assigning the $supplier a new doctrine object.
精彩评论