Take the 2-minute tour ×

Ok, I have two tables, users and units. 'Unit' belongsTo 'User', and 'User' hasMany 'Unit'. I would like to access all of the data from my units table, and append SOME of the data from my users table for the view. Here is my controller code:

public function condos() {
    $u=$this->User->Unit->find('all', array('conditions'=>array('type'=>'condo',     'active'=>1)));
    $this->set('allcondos', $u);

I have two models, User and Unit, here is the code for them: from unit.php:

class Unit extends AppModel {
    var $name='Unit';
    var $belongsTo=array(
    ) );

and from user.php:

class User extends AppModel {
    var $name='User';
    var $hasMany=array(
    ) );

Here is my view code:

<?php foreach ($allcondos as $condo) { ?>

<section class="listings">
<img src="<?php echo $condo['Unit']['photo1']; ?>" />
<h1><?php echo $condo['Unit']['complex'], ' ', $condo['Unit']['unitnum']; ?></h1>
<h2><?php echo $condo['Unit']['city']; ?>, <?php echo $condo['Unit']['state']; ?> | (<?php echo $condo['User']['area_code']; ?>)<?php echo $condo['User']['exchange'];?>-<?php echo $condo['User']['sln'];?></h2>
<p><?php echo $condo['Unit']['unit_desc']; ?></p>
<?php } ?>

I have a problem with the call to $condo['User']['any_field'] as it returns zero 'User' data. (It returns the 'Unit' data just fine). I don't know how to access both tables, obviously.

If I debug $allcondos in the view, it looks like this:

    [0] => Array
        [Unit] => Array
                [id] => 1
                [user_id] => caribeincrentals
                [additional fields] ...

        [User] => Array
                [id] => 
                [user_id] => 
                [additional fields] ...

    [1] => Array ...
share|improve this question
what is your table structure? –  Farray Dec 12 '11 at 23:11
i have a table users that has a bunch of info, including a field for 'user_id'. I have a units table that has bunch of info, including a field for 'user_id'. I altered my code again in my controller to say this: public function condos() { $this->User->Unit->Behaviors->load('Containable'); $u=$this->User->Unit->find('all', array( 'conditions'=>array( 'Unit.type'=>'condo', 'Unit.active'=>1), 'contain'=>array('User') )); $this->set('allcondos', $u); } and now I get data for units, PLUS the FIELDS for the users table but no data for the fields in the associative array –  huzzah Dec 12 '11 at 23:29
Does it work if you ignore containable behavior and instead specify recursive in your find()? –  Farray Dec 13 '11 at 0:15
I tried setting it to 1 first on $this->User->Unit, then $this->User, then $this->Unit, and none of them worked. –  huzzah Dec 13 '11 at 16:32
please post the output of debug( $allcondos ); in your view. –  Farray Dec 13 '11 at 16:37

2 Answers 2

up vote 0 down vote accepted

Without your database details, it is tough to say exactly what is going on. However, you seem to be using a string value as the foreignKey that links your 2 models together. This is a bad idea.

I suggest changing the user_id fk to an int datatype that references the id key column on the Users table (well, assuming that id is an autoincrementing integer value).

It's tough to say if this is the exact problem, but it's definitely worth checking out and will help you avoid some other headaches in the future.


If you structure your tables according to Cake conventions, most of the associative work will be done for you. Here's how I would do it:

Users table ('users'):

id        primary key (int)

User model:

$hasMany = array( 'Unit' );

Units table ('units'):

id        primary key (int)
user_id   corresponds to id in users table

Unit model:

$belongsTo = array( 'User' );

If you set your tables & models up like that, Cake will automatically associate 'user_id' in the units table with 'id' in the users table.

share|improve this answer
Can you explain to me why this is a bad idea? If I have x number of users, that may each have x number of units, how can I ever match them by id, as it is autoincrementing? I am confused. I thought I was supposed to have one field in each table that matches up exactly with the other? –  huzzah Dec 13 '11 at 17:03
@HeatherWalters It creates extra maintenance burden for you. id is already unique, auto-incrementing (has a default value), and small. user_id as a text/varchar field requires more space, carefully defined constraints, etc. It also leads to a massive update burden (thus threatening your db consistency) if you ever want to change a user_id value. Better to have a user-friendly user_id field for display-purposes only, and use the id field for all your fk associations behind the scenes. –  Farray Dec 13 '11 at 17:46
So, in my two AppModel.php files, how do I "make the association"? How do I say User.id is tied to every Unit.id that has a user_id of "someuser"? –  huzzah Dec 13 '11 at 17:57
@HeatherWalters same way you did with your text field. Just change the field name to the id field instead of user_id. And instead of using user's text representations, use their unique id. Cake will actually do this automagically for you if you use this naming convention. book.cakephp.org/view/1039/… –  Farray Dec 13 '11 at 18:00
Woo hoo, it worked!!!!!! You rock, thank you! I actually took out the "foreignKey=>'id' in my User.php file, and removed the containable feature in my controller and BLAMMO. Thanks again. –  huzzah Dec 13 '11 at 19:04
$this->Unit->find('all', array(
        'conditions' => array(
            'type' => 'condo',
            'active' => 1,
        'contain' => array(

Use containable to get related data. You can use conditions within that contain as well to restrict what information you want.


share|improve this answer
Hmm, it still doesn't pull any 'User' data. Seems like I am missing something still. –  huzzah Dec 12 '11 at 22:51
I altered my controller code. public function condos() { $this->User->Behaviors->load('Containable'); $u=$this->User->contain('Unit'); $u=$this->User->find('all'); $this->set('allcondos', $u); } It isn't associating the models together apparently because now I get all my data for User but not for Unit. –  huzzah Dec 12 '11 at 23:09

Your Answer


