I'm trying to do an association of two objects with Doctrine (PHP).

I have two objects : User and Conversation

One user has many conversations and a conversation belongs to two users maximum (on initiator of the conversation, and one receiver).

So, in my Doctrine class I have this in the Conversation class :

$this->hasOne('User as Initiator', array('local' => 'initiator_id', 'foreign' => 'id'));
$this->hasOne('User as Responder', array('local' => 'responder_id', 'foreign' => 'id'));

And in the User class :

$this->hasMany('Conversation as Conversations', array('local'=> 'id', 'foreign'=> ????));

For this foreign key I'd like to put something that means "initiator_id OR responder_id".

I guess I need a junction table to accomplish what I want to do ? What would you do in this case ?

Thank you for your answers,

Martin

Accepted Answer

I think it would be better to re model the relation between the Conversation and User tables to manytomany. because even though a conversation have only 2 users, they are still considered more than one.

In the previous solution, Having Two has-many relations with the same table (Conversation) is an over head. because you will end up doing twice the work every time you query a a conversation.

My suggestion is to change the relation between the conversion and the user to hasMany and reference them using an association class ConversationParticipants that contains the conversion_id, user_id and an additional association attribute called type to indicate the type of the user (Initiator/Responder).

So you will end up with something similar to this ( the code is not tested !)

class Conversation extends Doctrine_Record {

    public function setTableDefinition() {

        // Your Table Fields
    }

    public function setUp() {

        // Your Setup Code

        $this->hasMany('User as Users', array(
                'local' => 'conversation_id',
                'foreign' => 'user_id',
                'refClass' => 'ConversationParticipants'
            )
        );
    }

}

class User extends BaseUser
{

    public function setTableDefinition() {

        // Your User Fields

    }

    public function setUp()
    {

        // Your Setup Code

        $this->hasMany('Conversation as Conversations', array(
                'local' => 'user_id',
                'foreign' => 'conversation_id',
                'refClass' => 'ConversationParticipants'
            )
        );
    }
}

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

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

        $this->hasColumn('type', 'string', 255);

    }
}

This is how i would've implemented it on any ORM, I'm not sure though if you can use association attributes in Doctrine or if this way of molding is going to work as I'm not an expert in Doctrine

I Hope this was helpful ,,,

Written by Manaf Abu.Rous
This page was build to provide you fast access to the question and the direct accepted answer.
The content is written by members of the stackoverflow.com community.
It is licensed under cc-wiki