Brian Kerr
Brian Kerr

Reputation: 401

CakePHP model association deep model contain

I've been struggling with this problem for some time now, and have matched the associations with various other Models in my CakePHP applicaiton, but still can not get the result array to contain the associated ExpenseType.

Everything Starts with Property, which is defined as:

var $recursive = 2;

var $actsAs = array('Containable');

Model Associations

Property hasMany Bill

Bill belongsTo Property

Bill hasOne ExpenseType

ExpenseType belongsTo Bill


In My PropetiesController, I call and assign to $property:

$this->Property->findById($id);

This results in:

Array
(
[Property] => Array
    (
        [id] => 2
        [address] => **
        [bedrooms] => 2
        [bathrooms] => 1.5
        [square_footage] => 973
        [zip_code] => **
        [created] => 2013-08-13 18:30:34
        [modified] => 2013-08-15 19:08:32
    )

[Bill] => Array
    (
        [0] => Array
            (
                [id] => 2
                [expense_type_id] => 1
                [property_id] => 2
                [frequency] => monthly
                [start_date] => 2013-09-16
                [payee] => **
                [amount] => **
                [created] => 2013-08-20 19:57:41
                [modified] => 2013-08-20 20:57:02
            )

        [1] => Array
            (
                [id] => 4
                [expense_type_id] => 4
                [property_id] => 2
                [frequency] => monthly
                [start_date] => 2013-09-15
                [payee] => **
                [amount] => 195
                [created] => 2013-08-20 20:38:11
                [modified] => 2013-08-20 20:38:11
            )

    )
)

For the life of me, I can not get the array to contain the details of ExpenseType under Bill. Suggestions please!

UPDATE: When setting the contain method on the model, Cake now reports:

Model "Bill" is not associated with model "ExpenseType"

Bill Model

    class Bill extends AppModel {
        /*******************
        * Variables        *
        *******************/
        var $actsAs = array('Containable');

        /*********************
        * Model Associations *
        **********************/
        public $belongsTo = array('Property');
        public $hasOne = array('ExpenseType');
    }

ExpenseType Model

class ExpenseType extends AppModel {
    /*******************
    * Variables        *
    *******************/
    var $actsAs = array('Containable');

    /*******************
    * Model Associations      *
    *******************/
    public $belongsTo = array('Bill');
}

Table Structure

Upvotes: 4

Views: 2538

Answers (2)

Brian Kerr
Brian Kerr

Reputation: 401

I was able to get this to work by making the following changes:

Property Model

Changed:

public $hasMany = array(
        'Bill' => array(
            'className' => 'bills',
            'foreign_key' => 'property_id',
            'dependent' => true
            )
        );

To:

public $hasMany = array('Bill');

Bill Model

public $belongsTo = array('Property', 'ExpenseType');

ExpenseType Model

public $hasMany = array('Bill');

Seems the invalid association in the Property model was still allowing Bills to be queried, but somehow messed up the deeper associations. Not sure why it would work period.

Upvotes: 3

bowlerae
bowlerae

Reputation: 944

Some suggestions:

1.) Move recursive to PropertiesController right before findById

$this-Property->recursive = 2;

2.) Use containable behavior on Bill and ExpenseType models

var $actsAs = array('Containable');

...then in PropertiesController do...

$this->Property->contain(array(
    'Bill' => array(
        'ExpenseType'
    )
));

$this->set('property', $this->Property->findById($id));

UPDATE #1:

Bill Model

class Bill extends AppModel {
    /*******************
    * Variables        *
    *******************/
    var $actsAs = array('Containable');


    /*********************
    * Model Associations *
    **********************/
    public $belongsTo = array(
        'Property' => array(
            'className' => 'Property',
            'foreignKey' => 'property_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'ExpenseType' => array(
            'className' => 'ExpenseType',
            'foreignKey' => 'expense_type_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
    ); // end belongsTo
} // end Bill model

ExpenseType Model

class ExpenseType extends AppModel {
    /*******************
    * Variables        *
    *******************/
    var $actsAs = array('Containable');


    /*******************
    * Model Associations      *
    *******************/
    public $hasMany = array(
        'Bill' => array(
            'className' => 'Bill',
            'foreignKey' => 'expense_type_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
    ); // end hasMany

} // end ExpenseType model

then clear cache

Upvotes: 1

Related Questions