Trouble linking models together in CakePHP2

74 Views Asked by At

I'm using CakePHP 2.6.7.

Here is my database (simplified) :

***Users***
id
username

***Cars***
id
CarMake
CarModel
NumberPlate
user_id

***Addresses***
id
address
postalcode
city
country

***Addresses_Users***
user_id
address_id

This is what I want :

  • One user can have multiple cars and one car is owned by only one user.
  • One user can have multiple addresses and one address can by owned by multiple users.
  • One car can have multiple addresses and one address can be owned by multiple cars.

So right now I have a model User.php :

<?php
class User extends AppModel {

     public $hasMany = array(
         'Car' => array(
             'classname' => 'Car')
     );

     public $hasAndBelongsToMany = array(
         'Address' => array(
             'classname' => 'Address')
     );
?>

And a model Car.php :

<?php
class Car extends AppModel {

     public $belongsTo = array(
         'User' => array(
             'className' => 'User'
         )
     );

     public $hasMany = array(
         'Address' => array(
             'classname' => 'Address')
     );
}
?>

And a model Address.php :

<?php
class Address extends AppModel {

     public $belongsTo = array(
         'User' => array(
             'className' => 'User'
         ),

         'Car' => array(
             'classname' => 'Car')
     );
 }
 ?>

I tried to link cars with addresses but I can't get it to work... If I do a debug($this->User->find()); I have this result :

array(
'User' => array(
    'id' => '1',
    'username' => 'wblondel',
),
'Car' => array(
    (int) 0 => array(
        'id' => '2',
        'CarMake' => 'Allard',
        'CarModel' => '2005',
        'NumberPlate' => '56QDS1',
        'user_id' => '1',
    ),
    (int) 1 => array(
        'id' => '5',
        'CarMake' => 'Alvis',
        'CarModel' => '25',
        'NumberPlate' => '5lDS1',
        'user_id' => '1',
    )
),
'Address' => array(
    (int) 0 => array(
        'id' => '2',
        'address' => 'fghfghgf',
        'postalcode' => '78200',
        'city' => 'buchelay',
        'country' => '40'
    ),
    (int) 1 => array(
        'id' => '3',
        'address' => 'jkjkjk',
        'postalcode' => '69100',
        'city' => 'villeurbanne',
        'country' => '59'
    )
)
)

What I would firstly like is that in each car there is an array "address"...

Thanks!

2

There are 2 best solutions below

1
drmonkeyninja On BEST ANSWER

From what you've described your associations look wrong. They should be something like:-

User

<?php
class User extends AppModel {

    public $hasMany = array(
        'Car'
    );

    public $hasAndBelongsToMany = array(
        'Address'
    );
}

Car

<?php
class Car extends AppModel {

    public $belongsTo = array(
        'User'
    );

    public $hasAndBelongsToMany = array(
        'Address'
    );
}

Address

<?php
class Address extends AppModel {

    public $hasAndBelongsToMany = array(
        'Car',
        'User'
    );
}

You don't need to use className unless the alias you want to use is different from the model name or the model belongs to a plugin.

Then if you use the Containable behavior you should be able to get everything back using something like:-

$this->User->find(
    'all',
    array(
        'contain' => array(
            'Address',
            'Car' => array( 
                'Address'
            )
        )
    )
);
0
nIcO On

To control what exactly is retrieved from a find() query, you can use the ContainableBehavior.

By the way I think you have an error in your Address model as an address doesn't "belong to" a user, but can have many ones. It should be an HABTM relation as you have done in the User model.