Toki
Toki

Reputation: 175

Two relationships between two tables using the conventions of cakephp

Following a convention, how to make a table with two foreign keys to the same table. Taking as an example the blog tutorial, and the tutorial Simple Authentication and Authorization Application, where the table has a user_id post that represents the creator of the post referencing the user table. How to design the to store table, apart from the developer, another user may be the modifier.

CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50),
    password VARCHAR(50),
    role VARCHAR(20),
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL,
    user_id INT(11);// cakephp here knows the relationship itself
);

Obviously I can not add another column user_id to represent the user which amends. How I can do that, is it possible? Sorry for my English

Upvotes: 1

Views: 892

Answers (1)

thaJeztah
thaJeztah

Reputation: 29137

CakePHP conventions are created for several reasons; to be consistent and to reduce the amount of configuration required to make your application work.

However, CakePHP does not forbid you to use naming that are not following the conventions. In some situations you will have to disregard the conventions (think of a third-party database that will be used for a CakePHP project that doesn't follow CakePHP conventions) and your situation is one of them.

multiple relations to the 'same' model

Cake allows you to set an different alias for a model for each relation. This way, you can achieve what you describe in your question, without having conflicts. However, because the foreign key of thd second relation will not be following the CakePHP conventions, CakePHP wil not automatically pick the right column, so you will have to specify this yourself.

For example

class Post extends AppModel {

    public $belongsTo = array(
        // CakePHP will automatically use 'user_id' as foreign key
        'User',

        // Here we create an 'alias' for the User Model
        // also, we need to specify the foreign key to use
        // for the relation
        'Editor' => array(
            'className'   => 'User',       // name of the Model
            'foreignKey'  => 'editor_id',  // foreign key for this relation
        ),
    );
}

The Post model now has two relations to the User model. One with an alias Editor The alias works the same way as a 'regular' model; i.e. just like there was a Editor model attached to the Post;

In you controller, both find() will return all users, and actually use the 'User' model:

$this->Post->User->find('all');
$this->Post->Editor->find('all');

important

CakePHP uses aliases to cache model-information. If you use an alias for a model, you should never use the same alias for another model. CakePHP may use the cached information of the other model in those situations, leading to unpredictable results!

For example

class Post extends AppModel {
    public $belongsTo = array(
       'Editor' => array(
            'className'   => 'User',
            'foreignKey'  => 'editor_id',
        ),
    );
}

class Comment extends AppModel {
    public $belongsTo = array(
       'Editor' => array(
            'className'   => 'Visitor',    // WRONG!! Editor alias is already 
                                           // used as alias for the User model!
            'foreignKey'  => 'editor_id',
        ),
    );
}

Upvotes: 5

Related Questions