dealing-with-relations.txt 4.32 KB
Newer Older
zYne's avatar
zYne committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
+++ Creating related records

Accessing related records in Doctrine is easy: you can use exactly the same getters and setters as for the record properties. 

You can use any of the three ways above, however the last one is the recommended one for array portability purposes.

<code type="php">
$user->Email;

$user->get('Email');

$user['Email'];
</code>

When accessing a one-to-one related record that doesn't exist, Doctrine automatically creates the object. So for example the following code is possible:

<code type="php">
$user = new User();
$user->name = 'some user';

$user->Email->address = 'some@one.info';
// saves the user and the associated email
$user->save();
</code>

zYne's avatar
zYne committed
26
When accessing one-to-many related records, Doctrine creates a Doctrine_Collection for the related component. Lets say we have users and phonenumbers and their relation is one-to-many. You can add phonenumbers easily as shown above:
zYne's avatar
zYne committed
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

<code type="php">
$user = new User();
$user->name = 'some user';

$user->Phonenumber[]->phonenumber = '123 123';
$user->Phonenumber[]->phonenumber = '456 123';
$user->Phonenumber[]->phonenumber = '123 777';

// saves the user and the associated phonenumbers
$user->save();
</code>

+++ Retrieving related records

zYne's avatar
zYne committed
42
You can retrieve related records by the very same {{Doctrine_Record}} methods as in the previous subchapter. Please note that whenever you access a related component that isn't already loaded Doctrine uses one SQL SELECT statement for the fetching, hence the following example executes 4 SQL SELECTs.
zYne's avatar
zYne committed
43 44

<code type="php">
zYne's avatar
zYne committed
45 46
$user = $conn->getTable('User')->find(5);

zYne's avatar
zYne committed
47 48 49 50 51 52 53
print $user->Email['address'];

print $user->Phonenumber[0]->phonenumber;

print $user->Group[0]->name;
</code>

zYne's avatar
zYne committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
Much more efficient way of doing this is using DQL. The following example uses only one SQL query for the retrieval of related components.

<code type="php">
$user = Doctrine_Query::create()
        ->from('User u')
        ->leftJoin('u.Email e')
        ->leftJoin('u.Phonenumber p')
        ->leftJoin('u.Group g')
        ->execute();

print $user->Email['address'];

print $user->Phonenumber[0]->phonenumber;

print $user->Group[0]->name;
zYne's avatar
zYne committed
69
</code>
zYne's avatar
zYne committed
70

zYne's avatar
zYne committed
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

+++ Updating related records

You can update the related records by calling save for each related object / collection individually or by calling save on the object that owns the other objects. You can also call {{Doctrine_Connection::flush}} which saves all pending objects.

<code type="php">
$user->Email['address'] = 'koskenkorva@drinkmore.info';

$user->Phonenumber[0]->phonenumber = '123123';

$user->save();

// saves the email and phonenumber
</code>


+++ Deleting related records

zYne's avatar
zYne committed
89
You can delete related records individually be calling {{delete()}} on a record or on a collection.
zYne's avatar
zYne committed
90 91 92 93 94 95 96 97 98 99

<code type="php">
$user->Email->delete();

$user->Phonenumber[3]->delete();

// deleting user and all related objects:

$user->delete();
</code>
zYne's avatar
zYne committed
100 101 102 103 104 105 106 107

Usually in a typical web application the primary keys of the related objects that are to be deleted come from a form. In this case the most efficient way of deleting the related records is using DQL DELETE statement. Lets say we have once again users and phonenumbers with their relation being one-to-many. Deleting the given phonenumbers for given user id can be achieved as follows:

<code type="php">
$deleted = Doctrine_Query::create()
           ->delete()
           ->from('Phonenumber')
           ->addWhere('user_id = ?', array($userId))
zYne's avatar
zYne committed
108
           ->whereIn('id', $phonenumberIds);
zYne's avatar
zYne committed
109 110 111 112 113
           ->execute();
// print out the number of deleted phonenumbers
print $deleted;
</code>

zYne's avatar
zYne committed
114 115 116 117 118 119
Sometimes you may not want to delete the phonenumber records but to simply unlink the relations by setting the foreing key fields to null. This can ofcourse be achieved with DQL but perhaps to most elegant way of doing this is by using Doctrine_Record::unlink(). Please note that the unlink method is very smart. It not only sets the foreign fields for related phonenumbers to null but it also removes all given phonenumber references from the User object.

Lets say we have a User who has 3 Phonenumbers (with identifiers 1, 2 and 3). Now unlinking the Phonenumbers 1 and 3 can be achieved as easily as:

<code type="php">
$user->unlink('Phonenumber', array(1, 3));
zYne's avatar
zYne committed
120

zYne's avatar
zYne committed
121 122
$user->Phonenumber->count(); // 1
</code>