Lets say we have two classes User and Group which are linked trhough a GroupUser association class. When working with transient (new) records the fastest way for adding a User and couple of Groups for it is:
<code type='php'>
$user = new User();
$user->name = 'Some User';
$user->Group[0]->name = 'Some Group';
$user->Group[1]->name = 'Some Other Group';
$user->save();
</code>
However in real world scenarious you often already have existing groups, where you want to add a given user. The most efficient way of doing this is:
<code type='php'>
$gu = new GroupUser();
$gu->user_id = $userId;
$gu->group_id = $groupId;
$gu->save();
</code>
+++ Deleting a link
While the obvious and convinient way of deleting a link between User and Group would be the following, you still should *NOT* do this:
<code type='php'>
$user = $conn->getTable('User')->find(5);
$user->GroupUser
->remove(0)
->remove(1);
</code>
The right way to delete links between many-to-many associated records is by using the DQL DELETE statement. Convenient and recommended way of using DQL DELETE is trhough the Query API.
Whenever you fetch an object that has not all of its fields loaded from database then the state of this object is called proxy. Proxy objects can load the unloaded fields lazily.
Lets say we have a User class with the following definition:
In the following example we fetch all the Users with the fields name and password loaded directly. Then we lazy-load a huge field called description for one user.
// the following lazy-loads the description fields and executes one additional database query
$users[0]->description;
</code>
Doctrine does the proxy evaluation based on loaded field count. It does not evaluate which fields are loaded on field-by-field basis. The reason for this is simple: performance. Field lazy-loading is very rarely needed in PHP world, hence introducing some kind of variable to check which fields are loaded would introduce unnecessary overhead to basic fetching.