Search code examples
phpcakephprecursioncakephp-model

CakePHP Recursive not working with loadModel and this->set


Recursion does not seem to be working when I use $this->loadModel, I want to say I remember something about having to explicitly set the belongsTo and hasMany in this situation, but that seems anti-cakephp-auto-magical, I have yet to find any answers stating how to use

$this->loadModel 

and

$this->...->find('all', array('recursive' => 2));  

any ideas on why this isnt working is greatly appreciated.

$this->loadModel('DeployablesJoin');
$deployablesJoins = $this->DeployablesJoin->find('all', array('recursive' => 2));

$this->loadModel('DeployablesComplete');
$deployablesCompletes = $this->DeployablesComplete->find('all', array('recursive' => 2, 'conditions' => array('successful' => array('0', '-1'))));

$this->set('deployablesCompletes', $deployablesCompletes);
$this->set('deployablesJoins', $deployablesJoins);

Edit: Full Code Below

My DeployablesJoin Model

class DeployablesJoin extends NodeCncAppModel {

    public $actsAs = array('Containable');

    public $belongsTo = array(
        'Deployable' => array(
            'className' => 'Deployable',
            'foreignKey' => 'deployable_id',
            'conditions' => '',
            'fields' => 'title,filename,created',
            'order' => ''
        ),
        'ServerClass' => array(
            'className' => 'ServerClass',
            'foreignKey' => 'server_class_id',
            'conditions' => '',
            'fields' => 'name',
            'order' => ''
        )
    );
}

Relevant part of the controller

    $this->loadModel('DeployablesJoin');
    $deployablesJoins = $this->DeployablesJoin->find('all');

    print_r($deployablesJoins); die();

Results from print_r/die

Array ( 
    [0] => Array ( 
        [DeployablesJoin] => Array ( 
            [id] => 1 
            [deployable_id] => 5 
            [server_class_id] => 1 
        ) 
    ) 
)

What I have found that does work is the following (relevant part controller)

$this->loadModel('DeployablesJoin');
$this->DeployablesJoin->belongsTo = array(
    'Deployable' => array(
        'className' => 'Deployable',
        'foreignKey' => 'deployable_id',
        'conditions' => '',
        'fields' => 'title,filename,created',
        'order' => ''
    ),
    'ServerClass' => array(
        'className' => 'ServerClass',
        'foreignKey' => 'server_class_id',
        'conditions' => '',
        'fields' => 'name',
        'order' => ''
    )
);
$deployablesJoins = $this->DeployablesJoin->find('all');

print_r($deployablesJoins); die();

Results from print_r/die

Array ( 
    [0] => Array ( 
        [DeployablesJoin] => Array ( 
            [id] => 1 
            [deployable_id] => 5 
            [server_class_id] => 1 
        ) 
        [Deployable] => Array ( 
            [title] => asdf 
            [filename] => 5_agent.zip 
            [created] => 2015-01-09 21:31:25 
        ) 
       [ServerClass] => Array ( 
            [name] => Crawler 
       ) 
 )

When I do a print_r/die on $this->DeployablesJoin, I get the following

AppModel Object
(
    [useDbConfig] => default
    [useTable] => deployables_joins
    [id] => 
    ...
    [table] => deployables_joins
    [primaryKey] => id
    ...
    [name] => DeployablesJoin
    [alias] => DeployablesJoin
    [tableToModel] => Array
        (
            [deployables_joins] => DeployablesJoin
        )

    [cacheQueries] => 
    [belongsTo] => Array
        (
        )

Solution

  • There doesn't appear to be any reason your 'recursive' would not be working other than the associations set up incorrectly. I would suggest verifying those.

    That being said, using recursive 2 is considered bad practice. Instead, set recursive to -1, and use CakePHP's amazing Containable Behavior to retrieve any additional information.

    Another "best practice" change would be to put your finds into model methods instead of in the Controllers. So, in your case, it would be something like this:

    // in the controller
    $this->loadModel('DeployablesJoin');
    $deployablesJoins =  $this->DeployableJoin->getAll();
    
    //in the DeployablesJoin model
    public function getAll() {
        $this->recursive = 2; // should change this to containable instead though
        return $this->find('all');
    }