You are currently reading the 1.2 documentation. Switch to 2.0 
Equal Nest Relations

Equal nest relations are perfectly suitable for expressing relations where a class references to itself and the columns within the reference class are equal.

This means that when fetching related records it doesn't matter which column in the reference class has the primary key value of the main class.

The previous clause maybe hard to understand so lets take an example. We define a class called User which can have many friends. Notice here how we use the 'equal' option.

// models/User.php

class User extends BaseUser
{
    public function setUp()
    {
        parent::setUp();

        // ...

        $this->hasMany('User as Friends', array(
                'local'    => 'user1',
                'foreign'  => 'user2',
                'refClass' => 'FriendReference',
                'equal'    => true,
            )
        );
    }
}

// models/FriendReference.php

class FriendReference extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('user1', 'integer', null, array(
                'primary' => true
            )
        );

        $this->hasColumn('user2', 'integer', null, array(
                'primary' => true
            )
        );
    }
}

Here is the same example in YAML format. You can read more about YAML in the YAML Schema Files chapter:

---
# schema.yml

# ...
User:
# ...
  relations:
    # ...
    Friends:
      class: User
      local: user1
      foreign: user2
      refClass: FriendReference
      equal: true

FriendReference:
  columns:
    user1:
      type: integer
      primary: true
    user2:
      type: integer
      primary: true

Now lets define 4 users: Jack Daniels, John Brandy, Mikko Koskenkorva and Stefan Beer with Jack Daniels and John Brandy being buddies and Mikko Koskenkorva being the friend of all of them.

// test.php

// ...
$daniels = new User();
$daniels->username = 'Jack Daniels';

$brandy = new User();
$brandy->username = 'John Brandy';

$koskenkorva = new User();
$koskenkorva->username = 'Mikko Koskenkorva';

$beer = new User();
$beer->username = 'Stefan Beer';

$daniels->Friends[0] = $brandy;

$koskenkorva->Friends[0] = $daniels;
$koskenkorva->Friends[1] = $brandy;
$koskenkorva->Friends[2] = $beer;

$conn->flush();

Calling Doctrine_Connection::flush() will trigger an operation that saves all unsaved objects and wraps it in a single transaction.

Now if we access for example the friends of Stefan Beer it would return one user 'Mikko Koskenkorva':

// test.php

// ...
$beer->free();
unset($beer);
$user = Doctrine_Core::getTable('User')->findOneByUsername('Stefan Beer');

print_r($user->Friends->toArray());

Now when you execute test.php you will see the following:

$ php test.php
Array
(
    [0] => Array
        (
            [id] => 4
            [is_active] => 1
            [is_super_admin] => 0
            [first_name] =>
            [last_name] =>
            [username] => Mikko Koskenkorva
            [password] =>
            [type] =>
            [created_at] => 2009-01-20 16:53:13
            [updated_at] => 2009-01-20 16:53:13
        )

)

Questions and Feedback

If you find a problem with the documentation or have a suggestion, please register and open a ticket.

If you need support or have a technical question, you can post to the user mailing-list.